从C++11开始,C++可以使用变长模板参数,能让函数接受任意数量的参. ,有时这些参数都组合成一个表达式,从中得到函数结果。可变模板参数比较抽象,使用起来需要一定的技巧,因为其需要一定的技巧才能使用,所以会显得比较有意思。
可变模板参数函数
可变模板参数函数的声明:
可变模板参数函数的声明和模板函数的声明类似,唯一不同的是需要在表示其抽象类型时即在关键字typename或者class的后面添加上省略号“…”。示例如下:
1 | template<typename ...Args>//template<class ...Args> |
省略号的作用:
1.声明一个参数包,包含任意个参数
2.在模板定义的右边,可以将参数展开成一个一个独立的参数
展开参数包的方法有两种:
1.通过递归的模板函数展开
2.通过逗号表达式和初始化列表方式展开
1.通过递归的模板函数展开参数包
1 |
|
在使用递归的方式展开模板参数的时候,需要指定递归终止函数。递归终止函数与可变模板参数的函数同名。且当参数包中剩余的参数个数等于递归终止函数的参数个数时,会调用递归终止函数。
2.通过逗号表达式和初始化列表方式展开
使用递归函数比较好理解如何展开参数包,而使用逗号表达式和初始化列表的方式可能不那么容易理解,其中最关键的就是对于逗号表达式的理解。如果理解了逗号表达式那么应该也就很好理解了。逗号表达式示例:
1 | z = (x=y,m); |
对于括号中的求值顺序是从左往右,意思就是先进行 x=y的运算,将y赋值给x,然后将括号中的m赋值给z,这样z的值就为m。示例代码如下:
1 |
|
其展开式为 {(show_list(arg0),0)…},{(show_list(arg0),0),(show_list(args1),0)…},{(show_list(arg0),0),(show_list(args1),0),(show_list(args2),0)…}…,{(show_list(arg0),0),(show_list(args1),0),(show_list(args2),0),….,(show_list(argsn),0)}.最终会创建一个元素全部为0的数组。
下面是使用列表初始化和lambda函数的示例:
1 |
|
可变参数模板类
当然也可以使用可变模板参数来对结构体或者类进行声明,请声明方式如下:
1 | template <typename ...Args> // template<class ...Args> |
对于可变参数模板类来说,模板的参数个数可以为任意个。但是可变参数模板类的展开可以通过两个方式进行展开:
1.通过模板偏特化和递归的方式展开
2.通过继承的方式展开参数包
1.通过模板偏特化和递归的方式展开
如下代码所示:
1 |
|
需要注意不要忘记声明递归终止的类,否则会出错哦。
2.通过继承的方式展开参数包
1 |
|