C++ template
#参考yanxiangtianji 的博客
1,模板参数包(template parameter pack):
它指模板参数位置上的变长参数(可以是类型参数,也可以是非类型参数)
2,函数参数包(function parameter pack):
它指函数参数位置上的变长参数
1参数包:
1 #include <iostream> 2 #include <algorithm> 3 #include <tuple> 4 using namespace std; 5 6 //==========================template==========================// 7 template <typename ... Types1,template <typename ...> class T, 8 typename ... Types2,template <typename ...> class V> 9 void bar(const T<Types1 ...>&,const V<Types2 ...>&) 10 { 11 12 std::cout << sizeof...(Types1) << std::endl; 13 std::cout << sizeof...(Types2) << std::endl; 14 }; 15 16 17 //==========================template==========================// 18 19 int main() 20 { 21 //==========================template==========================// 22 23 cout<<"//===========================Template===============================================\n"<<endl; 24 tuple<int , double> a; 25 tuple<char,float,long> b; 26 bar(a,b); 27 28 //==========================template==========================// 29 30 return 0; 31 }
result:
2
3
Process finished with exit code 0
2解包:
1 template <typename ... Args> 2 class D1 : public Base<Args...>{}; 3 或 4 template <typename ... Args> 5 class D2 : public Base<Args>...{};
解包用两种常见的形式:
1,直接解包(上面第一个)
D1<X,Y,Z> 相当于 D1:public Base<X,Y,Z>
2,先参与其他表达式再解包(上面第二个)
D2<X,Y,Z> 相当于 D2: public Base<X>, Base<Y>, Base<Z>
1 template <typename ... T> 2 void fun_1(T ...t) 3 { 4 std::cout << sizeof...(t) << std::endl; 5 } 6 template <typename T> 7 void fun_2(T t) 8 { 9 std::cout << sizeof...(t) << std::endl; 10 }
/C++/Template/practise_2/main.cpp: In function ‘void fun_2(T)’:
/Template/practise_2/main.cpp:24: error: expansion pattern ‘t’ contains no argument packs
很显然fun_2是不能解包的。
参数包的展开不能无条件地在任何地方使用,这会给编译器看到的源代码的结构带来很大的复杂性。严格来说标准规定可以进行参数包展开的有7中情 况:1,表达式;2,初始化列表;3,基类描述列表;4,类成员初始化;5,模板参数列表;6,通用属性列表;7,lambda函数的捕获列表。
第二个(fun_3(t)...)貌似是有意义的,但是一般情况下不能这样用,可以简单地认为:不能让展开之后的表达式成为一个独立的语句。
3例子:
递归解包
1 template <typename T> 2 void func_4(const T & t) 3 { 4 cout<<t<<endl; 5 }; 6 7 template <typename T,typename ... Args> 8 void func_4(const T & t,Args ... args) 9 { 10 cout<<t<<endl; 11 func_4(args ...); 12 }; 13 14 func_4(1,3,5,7,9); 15 16 1 17 3 18 5 19 7 20 9 21 22 Process finished with exit code 0
1 template <typename ...T> 2 void DumpMyWrapper(T ... t) 3 { 4 5 }; 6 template <class T> 7 T unpacker(const T & t) 8 { 9 cout<<"\n"<<t<<endl; 10 return t; 11 }; 12 template<typename ...Args> 13 void func_5(const Args & ...data) 14 { 15 DumpMyWrapper(unpacker(data)...); 16 cout<<"\n"; 17 }; 18 19 func_5(2,4,6,8,10); 20 10 21 22 8 23 24 6 25 26 4 27 28 2 29 30 31 Process finished with exit code 0
不能直接用(unpacker(data)...),需要包裹一下。
部分原载于http://blog.csdn.net/yanxiangtianji