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 }
View Code

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>...{};  
View Code

解包用两种常见的形式:

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 }
View Code

/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
View Code
 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
View Code

不能直接用(unpacker(data)...),需要包裹一下。

 

部分原载于http://blog.csdn.net/yanxiangtianji

 

posted @ 2017-08-17 16:26  HexOxZhw  阅读(306)  评论(0编辑  收藏  举报