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

#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));
		}
	};
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值