可变参数模板
可变参数模板:一个可变参数模板就是可变参数的模板函数或模板类
参数包: 可变数目的参数被称作参数包
•模板参数包:表示零个或多个模板参数
•函数参数包:表示零个或多个模板参数
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 = 0; double 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 }
运行结果: