15.7 可变参模板与模板模板参数

可变参模板:(Variadic Templates):允许模板中含有0个到任意个模板参数,在语法上也和传统模板不太一样,多了一个…

一:可变参函数模板

<1>简单范例
值得注意的内容:
1>我们一般把这个args称为一包或者一堆参数,而且这些参数的类型可以各不相同;
我们理解T这种类型的时候,不能把他理解成一个类型,你要理解成0到多个不同的类型,那自然,对应的参数args也应该是多个不同类型的参数;
2>这一包参数中可以容纳0到多个模板参数,而且这些模板参数可以为任意的类型;
3>大家注意把名字理顺一下:
T后边带了…,所以,我们称呼T:可变参类型;这个东西看起来是一个类型名,实际上里边包含的是0到多个不同的类型(一包类型);
args:可变形参,既然T代表的是一包类型,那显然args代表的就一包形参;
4>在具体函数形参中,&的位置,出现在了类型名的后边。

template <typename... T>
void myfunct1(T... args) //T:一包类型   ,args:一包形参
{
	cout << sizeof...(args) << endl;   //sizeof...可变参数量
	cout << sizeof...(T) << endl;
}

int main()
{
	myfunct1();
	myfunct1(10, 20);
	myfunct1(10, 25.8, "abc");
	return 0;
}

<2>参数包的展开:展开套路比较固定,一般都是用递归函数的方式来展开参数;
要求我们在代码编写中,有一个参数包展开函数,和一个同名的递归终止函数,我们就是通过这两个函数把参数包展开的;

//递归终止 函数
void myfunct2()
{
	cout << "参数包展开时执行了递归终止函数myfunc2()..." << endl;
}

template <typename T, typename...U>
void myfunct2(const T& firstarg, const U&... otherargs)  //一个参数,一包参数,这种可变参函数模板写法最适合参数包的展开
{
	//cout << sizeof...(otherargs) << endl;
	cout << "收到的参数值为:" << firstarg << endl;
	myfunct2(otherargs...); //递归调用,注意写法...
}

int main()
{
	myfunct2(10);
	myfunct2(10, "abc", 12.7);
	myfunct2("abc", 12.7);
	myfunct2(12.7);
	myfunct2();
	return 0;
}

二:可变参类模板

允许模板定义中含有0到任意个模板参数;
<1>通过递归继承方式展开参数包

template<typename... Args>
class MyClassST  //主模板
{
public:
	MyClassST()
	{
		printf("MyclassST::MyclassST()泛化版本执行了,this = %p \n", this);
	}
};

template<> class MyClassST<>  //0个模板参数的特化版本
{
public:
	MyClassST()
	{
		printf("myclasst<>::myclasst()特殊的特化版本执行了,this = %p\n", this);
	}
};

template<typename First, typename... Others>
class MyClassST<First, Others...> : private MyClassST<Others...>
{
public:
	MyClassST() : m_f(0)
	{
		cout << "-------------------begin----------------" << endl;
		printf("MyclassST::MyclassST()偏特化版本执行了,this = %p, sizeof...(Others) = %zd \n", this, sizeof...(Others));
		cout << "m_f = " << m_f << endl;
		cout << "-------------------end------------------" << endl;
	}

	MyClassST(First parf, Others... paro) : m_f(parf), MyClassST<Others...>(paro...)
	{
		cout << "-------------------begin----------------" << endl;
		printf("MyclassST(First parf, Others... paro)执行了,this = %p \n", this);
		cout << "m_f = " << m_f << endl;
		cout << "-------------------end------------------" << endl;
	}

public:
	First m_f;
	//MyClassST
};

int main()
{
	MyClassST<int, float, double> myc(12, 13.5, 23.7);
	//范例取材:标准库中的tuple(元组)
	return 0;
}

<2>通过递归组合方式展开参数包

template<typename... Args>
class MyClassST  //主模板
{
public:
	MyClassST()
	{
		printf("MyclassST::MyclassST()泛化版本执行了,this = %p \n", this);
	}
};

template<> class MyClassST<>  //0个模板参数的特化版本
{
public:
	MyClassST()
	{
		printf("myclasst<>::myclasst()特殊的特化版本执行了,this = %p\n", this);
	}
};

template<typename First, typename... Others>
class MyClassST<First, Others...>
{
public:
	MyClassST() : m_f(0)
	{
		cout << "-------------------begin----------------" << endl;
		printf("MyclassST::MyclassST()偏特化版本执行了,this = %p, sizeof...(Others) = %zd \n", this, sizeof...(Others));
		cout << "m_f = " << m_f << endl;
		cout << "-------------------end------------------" << endl;
	}

	MyClassST(First parf, Others... paro) : m_f(parf), m_o(paro...)
	{
		cout << "-------------------begin----------------" << endl;
		printf("MyclassST(First parf, Others... paro)执行了,this = %p \n", this);
		cout << "m_f = " << m_f << endl;
		cout << "-------------------end------------------" << endl;
	}

public:
	First m_f;
	MyClassST<Others...> m_o;
};

int main()
{
	MyClassST<int, float, double> myc(12, 13.5, 23.7);
	//范例取材:标准库中的tuple(元组)
	return 0;
}

<3>通过tuple和递归调用展开参数包

template<int mycount, int mymaxcount, typename... T>
class MyClassST2
{
public:
	static void mysfunc(const tuple<T...>& t)
	{
		cout << "value = " << get<mycount>(t) << endl;
		MyClassST2<mycount + 1, mymaxcount, T...>::mysfunc(t);
	};
};

template<int mymaxcount, typename... T>
class MyClassST2<mymaxcount, mymaxcount, T...>
{
public:
	static void mysfunc(const tuple<T...>& t)
	{

	};
};

template<typename... T>
void myfunctuple(const tuple<T...>& t)
{
	MyClassST2<0, sizeof...(T), T...>::mysfunc(t);
}

int main()
{
	tuple<float, int, int> mytuple(12.5f, 100, 52);
	myfunctuple(mytuple);
	return 0;
}

三:模板模板参数

有点难,暂时跳过。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值