![](https://img-blog.csdnimg.cn/img_convert/9289ae7c706e07bc4f21adf36cd746d4.png)
解释
C++03只有固定模板参数。C++11 加入新的表示法,允许任意个数、任意类别的模板参数,不必在定义时将参数的个数固定。
变长模板、变长参数是依靠C++11新引入的参数包的机制实现的。
参数包
template<class ... Types> struct Tuple { };
Tuple<> t0; // Types不含任何实参
Tuple<int> t1; // Types含有一个实参:int
Tuple<int, float> t2; // Types含有两个实参:int和float
Tuple<0> error; // 错误:0不是一个类型
template<class ... Types> void f(Types... args);
f(); // OK:args不含有任何实参
f(1); // OK:args含有一个实参:int
f(2, 1.0); // OK:args含有两个实参int和double
template <typename... TS> // typename... TS为模板形参包,TS为模式
static void MyPrint(const char* s, TS... args) // TS... args为函数形参包,args为模式
{
printf(s, args...);
}
解包
一个常用的技巧是:利用模板推导机制,每次从参数包里面取第一个元素,缩短参数包,直到包为空。
template <typename T>
void fun(const T& t){
cout << t << '\n';
}
template <typename T, typename ... Args>
void fun(const T& t, Args ... args){
cout << t << ',';
fun(args...);//递归解决,利用模板推导机制,每次取出第一个,缩短参数包的大小。
}
在C++17标准中,可以使用fold expression,更直接地表达,并且确保正序展开:
// C++17
template<typename T0, typename... T>
void printf(T0 t0, T... t) {
std::cout << t0 << std::endl;
if constexpr (sizeof...(t) > 0) printf(t...);
}
// C++11
#include <iostream>
template <typename T0>
void printf(T0 value){
std::cout << value << std::endl;
}
template <typename T, typename... Args>
void printf(T value, Args... args){
std::cout << value << std::endl;
printf(args...);
}
int main(){
printf(1, 2, "123", 1.1);
return 0;
}
关注公众号获取更多信息:
![](https://img-blog.csdnimg.cn/20201119102813792.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L01heF9Db25n,size_16,color_FFFFFF,t_70)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)