introduction#
C++11的新特性--可变模版参数(variadic templates)是C++11新增的最强大的特性之一,它对参数进行了高度泛化,表示0到任意个数、任意类型的参数.
可变模版参数函数#
1 | template <class... T> |
递归函数方式展开参数包#
1 | #include <iostream> |
逗号表达式展开参数包#
1 | template <class T> |
这种展开参数包的方式,不需要通过递归终止函数,是直接在expand函数体中展开的,
printarg不是一个递归终止函数,只是一个处理参数包中每一个参数的函数。这种就地展开参数包的方式实现的关键是逗号表达式。我们知道逗号表达式会按顺序执行逗号前面的表达式,比如:
1
d = (a = b, c);
expand函数中的逗号表达式:(printarg(args),
0),也是按照这个执行顺序,先执行printarg(args),再得到逗号表达式的结果0。同时还用到了C++11的另外一个特性——初始化列表,通过初始化列表来初始化一个变长数组,
{(printarg(args), 0)...}将会展开成
1
((printarg(arg1),0), (printarg(arg2),0), (printarg(arg3),0), etc... )
1
2
3
4
5
6
7template<class F, class... Args>
void expand(const F& f, Args&&...args)
{
//这里用到了完美转发,关于完美转发,读者可以参考笔者在上一期程序员中的文章《通过4行代码看右值引用》
initializer_list<int>{(f(std::forward< Args>(args)),0)...};
}
expand([](int i){cout<<i<<endl;}, 1,2,3);