可变参类模板,通过递归继承方式展开参数包

#include<iostream>
using namespace std;
/*泛化*/
template <typename... args>
class A
{
    
    
public:
    A()
    {
    
    
        cout << "泛化A<>(), this = " << this << endl;
    }  
};
/*特殊的版本,不是全特化*/
template <>
class A<> 
{
    
    
public:
    A()
    {
    
    
        cout << "特殊的版本A<>(), this = " << this << endl;
    }
};
/*偏特化*/
template <typename T, typename... args>
class A<T, args...> : public A<args...> //这里public继承也行,网上的很多是private继承
{
    
    
public:
    A(T v, args... vs): m_i(v), A<args...>(vs...) //要在初始化列表里调用 A<args...>的构造函数进行初始化操作
    {
    
    
        cout << "A<val, args...>, this = " << this << endl;
        cout << v << endl;
    }
    T m_i;
};
int main()
{
    
    
    /*可变参类模板,通过继承方式进行递归展开 
    这里当参数包展开到0的时候会调用全特化的版本,当然,
    如果没有全特化版本的就会去调用泛化版本的*/
    A<int, double, string> v(19, 20.5, "abcd");
}

在这里插入图片描述
上面的代码会生成以下的实例,具体的继承关系如下:

template <>
class A<>
{
    
    
public:
    A()
    {
    
    
        cout << "A<>(), this = " << this << endl;
    }
};

template <>
class A<string> : public A<>
{
    
    
public:
    A(string val) : m_i(val), A<>()
    {
    
    
        cout << "A<string> : " << m_i << endl;
    }
    string m_i;
};

template <>
class A<double, string> : public A<string>
{
    
    
public:
    A(double val, string arg1)
        : m_i(val), A<string>(arg1)
    {
    
    
        cout << "A<double, string>() : " << m_i << endl;
    }
    double m_i;
};

template <>
class A<int, double, string> : public A<double, string>
{
    
    
public:
    A(int val, double arg1, string arg2)
        : m_i(val), A<double, string>(arg1, arg2)
    {
    
    
        cout << "A<int, double, string>() : " << m_i << endl;
    }
    int m_i;
};

实例化时,先调父类的构造函数,后到子类的构造函数。

具体的实例可以利用vs里面的dumpbin命令把目标文件导出进行分析。
在这里插入图片描述
同样也可以用在非类型模板参数和模板模板参数上面

namespace _nmsp2
{
    
    
	//主模板定义(泛化版本的类模板)
	template <int ...FTArgs> //int 替换为auto也可以
	class myclasst2
	{
    
    
	public:
		myclasst2()
		{
    
    
			printf("myclasst2::myclasst2()泛化版本执行了,this = %p\n", this);
		}
	};

	template <int First, int ...Others> //int替换成auto也没问题
	class myclasst2<First, Others...> :private myclasst2<Others...> //偏特化
	{
    
    
	public:
		myclasst2()
		{
    
    
			printf("myclasst2::myclasst2()偏特化版本执行了,this = %p,sizeof...(Others)=%d,First=%d\n", this, sizeof...(Others), First);
		}
	};

}
namespace _nmsp3
{
    
    
	//泛化版本
	template<typename T,
		template<typename> typename... Container>
	class ParentMM
	{
    
    
	public:
		ParentMM()
		{
    
    
			printf("ParentMM::ParentMM()泛化版本执行了,this = %p\n", this);
		}
	};

	template<typename T,
		template<typename> typename FirstContainer,
		template<typename> typename... OtherContainers>
	class ParentMM<T, FirstContainer, OtherContainers...> :private ParentMM<T, OtherContainers...> //偏特化
	{
    
    
	public:
		ParentMM()
		{
    
    
			printf("ParentMM::ParentMM()偏特化版本执行了,this = %p,sizeof...(OtherContainers)=%d\n", this, sizeof...(OtherContainers));
			m_container.push_back(12);
		}
		FirstContainer<T>  m_container;
	};

	template<typename T,
		template<typename> typename... Container>
	class myclasst3 :private ParentMM<T, Container...>
	{
    
    
	public:
		myclasst3()
		{
    
    
			printf("myclasst3::myclasst3()执行了,this = %p,T的类型是:%s,Container参数个数是%d个\n",
				this,
				typeid(T).name(), 
				sizeof...(Container));
		}
	};
}

猜你喜欢

转载自blog.csdn.net/qq_38158479/article/details/121331247