可变模板参数
大约 2 分钟
可变模板参数
是新增的最强大的特性之一,它对参数进行了高度的泛化,它能表示**、**的参数。
模板参数包
template<typename… Args> class tuple;//tuple是元组的意思,其模板参数就是模板参数包
Args标识符的左侧使用了省略号
,在C++11中Args
被称为“模板参数包”,表示可以接受任意多个参数作为模板参数,编译器将多个模板参数打包成“单个”的模板参数包.
函数参数包
template<typename…T> void f(T… args);//args就是函数参数包
args
被称为函数参数包,表示函数可以接受多个任意类型的参数. 在C++11标准中,要求**必须唯一,且是函数的最后一个参数**; 则没有。 当使用参数包时,省略号位于参数名称的右侧,表示立即展开该参数,这个过程也被称为解包。
可变模板参数的优势
- 参数个数,那么对于模板来说,在模板推导的时候,就已经知道参数的个数了,也就是说在编译的时候就确定了,这样编译器就存在可能去优化代码
- 参数类型,推导的时候也已经确定了,模板函数就可以知道参数类型了。
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;
template <typename... Args>
void print(Args... args)
{
cout << "sizeof...(Agrs) = " << sizeof...(Args) << endl;
cout << "sizeof...(agrs) = " << sizeof...(args) << endl;
}
void display()
{
cout << endl;
}
template <typename T, typename... Args>
void display(T t, Args... args)
{
cout << t << " ";
display(args...);//当... 位于args右边的时候叫做解包
}
void test()
{
string s1 = "hello";
print();
print(1, 2.2);
print('a', true, s1);
print(1, 2.2, 'b', "hello");
}
void test2()
{
string s1 = "hello";
display();
display(1, 2.2);
display('a', true, s1);
display(1, 2.2, 'b', "hello");
}
template <class T>
T sum(T t)
{
return t;
}
template <typename T, typename... Args>
T sum(T t, Args... args)
{
return t + sum(args...);
}
void test3()
{
cout << "sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) = "
<< sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) << endl;
}
int main() {
test();
test2();
test3();
return 0;
}
$./a.out
sizeof...(Agrs) = 0
sizeof...(agrs) = 0
sizeof...(Agrs) = 2
sizeof...(agrs) = 2
sizeof...(Agrs) = 3
sizeof...(agrs) = 3
sizeof...(Agrs) = 4
sizeof...(agrs) = 4
1 2.2
a 1 hello
1 2.2 b hello
sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) = 55