【C++ Primer 第16章】4. 可变参数模板

可变参数模板

可变参数模板:一个可变参数模板就是可变参数的模板函数或模板类

参数包: 可变数目的参数被称作参数包

•模板参数包:表示零个或多个模板参数
•函数参数包:表示零个或多个模板参数

template <typename T, typename ... Args> 
void fun(T t, Args ... args);//合法 

template <typename ... Args, typename T> 
void fun(Args ... args, T t);//非法
 1 // Args是一个模板参数包; rest是一个函数参数包
 2 // Args表示零个或多个模板类型参数
 3 // rest表示林个或多个函数参数
 4 template <typename T, typename ... Args>
 5 void foo(const T &t, const Args& ... rest)
 6 
 7 int i = 0double  d = 3.14; strng s = "how now brown cow";
 8 foo(i, s, 42, d);
 9 foo(s, 42, "hi");
10 foo(d, 42);
11 foo("hi");
12 
13 void foo(const int&, const string&, const int&, const double&);
14 void(const string&, const int&, const char[3]&);
15 void foo(const double&, const string&);
16 void foo(const char[3]&);

sizeof...运算符

【注意】当我们需要知道包中有多少个元素时,可以用sizeof...

 1 #include<iostream>
 2 #include<string>
 3 using namespace std;
 4 
 5 template <typename T, typename ... Args>
 6 void foo(const T&, const Args& ... rest)
 7 {
 8     cout << sizeof...(Args) << " ";  //模板类型参数的数目
 9     cout << sizeof...(rest) << endl; // 函数参数的数目
10 }
11 
12 int main()
13 {
14     int i = 0; double  d = 3.14; string s = "how now brown cow";
15     foo(i, s, 42, d);
16     foo(s, 42, "hi");
17     foo(d, 42);
18     foo("hi");
19 
20     return 0;
21 }

运行结果:

编译可变参数函数模板

非可变参数模板比可变参数模板更特例化,因此编译器选择非可变参数版本。

 1 #include<iostream>
 2 #include<string>
 3 using namespace std;
 4 
 5 template <typename T>
 6 ostream& print(ostream &os, const T &t)
 7 {
 8     return os << t << endl;
 9 }
10 
11 template <typename T, typename ... Args>
12 ostream &print(ostream &os, const T &t, const Args& ... rest)
13 {
14     os << t << " , ";
15     return print(os, rest ...);
16 }
17 
18 int main()
19 {
20     int i = 0;
21     string s = "hello";
22     
23     print(cout, i);
24     print(cout, i, s);
25     print(cout, i, s, 42.1, 'A', "End");
26     return 0;
27 }

运行结果:

包扩展

 1 #include <iostream>
 2 using namespace std;
 3 
 4 template <typename T>
 5 T accum(const T &t)
 6 {
 7     return t;
 8 }
 9 
10 template <typename T, typename... Args>
11 T accum(const T &t, Args... args)
12 {
13     return t + accum(args...);
14 }
15 
16 int h()
17 {
18     return 42;
19 }
20 
21 template <typename ...Args>
22 int h(int t, Args ... args)
23 {
24     return t + h(args...);
25 }
26 
27 void f(int i, int j = 0, int k = 0, int l = 0)
28 {
29     cout << i << " + "
30         << j << " + "
31         << k << " + "
32         << l << " =  "
33         << i + j + k + l << endl;
34 }
35 
36 template<typename ... Args>
37 void g(Args ... args)
38 {
39     cout << sizeof...(Args) << endl;
40     cout << sizeof...(args) << endl;
41     f(args...);  // h(a1, a2, a3, ..., an)
42 
43     cout << h(args...) << endl; // h(a1, a2, a3, ..., an)
44 
45     f(h(args) ...);   // f(h(a1), h(a2), h(a3), ..., h(an))
46 
47     f(h(args ...));  // f(h(a1, a2, a3, ..., an2)
48 
49     f(h(5, 6, 7, 8) + args ...); // f(h(5,6,7,8) + a1, h(5,6,7,8) + a2, h(5,6,7,8) + a3, ..., h(5,6,7,8) + an)                              
50 }
51 
52 int main()
53 {
54     cout << accum(1, 2, 3, 4) << endl;
55     g(1, 2, 3, 4);
56     return 0;
57 }

运行结果:

猜你喜欢

转载自www.cnblogs.com/sunbines/p/9087283.html
今日推荐