C++的可变参数模板函数
可变参数模板函数写法:
模板参数里写typename... args,表明args是一个可变参数。
之后再函数参数里args后面也要加...,以表示该参数为可变参数。
函数参数中对于args的修饰,会扩展到所有该args的参数,比如下面代码:
//可变参数模板函数使用方法1:递归调用,每次将可变参数规模变小直到为0 template<typename T> void print(const T& x) { cout << "最后一次调用print,输出:" << x << endl; } template<typename T, typename... args> void print(const T& x, const args&... rest) { cout << "当前print函数输出:" << x << endl; cout << "当前print函数的可变参数长度为:" << sizeof...(rest) << endl; print(rest...); }
如果调用:int i=1,j=2,k=3;那么实际print(i,j,k)调用的是:print(const int& i,const int& j,const int& k);
//可变参数模板函数使用方法2:循环调用 template<typename... args> void print2(args&&... li) { for (auto x : { li... }) { cout << x << endl; } } int main() { int i = 0, j = 1, k = 2; print2(i, j, k); getchar(); return 0; }
另外据C++primer上说,可变参数模板函数一般用来将它的参数转发给其他函数,比如:
template<typename... args> void do_something(args... arg_list){ //blahblahblah } template<typename... args> void f(args&&... arg_list){ //这里arg后加了&&,将arg_list的所有参数都扩展为右值引用,方便接下来的转发 do_something(std::forward<args>(arg_list)...); } int main(){ int x1=1; const int x2=1; const int& x3=x2; int* x4=&x1; int&& x5=move(x1); f(x1,x2,x3,x4,x5,move(x1),1); getchar(); return 0; }
正好复习下转发:
f函数实际调用的样子是这样的:
可以看到完美转发的强大之处。。。所有的const、左右值、引用/指针性质全部原封不动转发给了do_something函数。
进击的小🐴农