32-模板和函数参数包
18.6.1 模板和函数参数包
为理解参数包的工作原理,首先来看一个简单的模板函数,它显示一个只有一项的列表:
template<typename T>
void show_list0(T value)
{
std::cout << value << ", ";
}
在上述定义中,有两个参数列表。模板参数列表只包含T,而函数参数列表只包含value。下面的函数调用将模板参数列表中的T设置为double,将函数参数列表中的value设置为2.15:
show_list0(2.15);
C++11提供了一个用省略号表示的元运算符(meta-operator),让您能够声明表示模板参数包的标识符,模板参数包基本上是一个类型列表。同样,它还让您能够声明表示函数参数包的标识符,而函数参数包基本上是一个值列表。其语法如下:
template<typename... Args> // Args is a template parameter pack
void show_list1(Args... args) // args is a function parameter pack
{
...
}
其中,Args是一个模板参数包,而args是一个函数参数包。与其他参数名一样,可将这些参数包的名称指定为任何符合C++标识符规则的名称。Args和T的差别在于,T与一种类型匹配,而Args与任意数量(包括零)的类型匹配。请看下面的函数调用:
show_list1('S', 80, "sweet", 4.5);
在这种情况下,参数包Args包含与函数调用中的参数匹配的类型:char、int、const char *和double。
下面的代码指出value的类型为T:
void show_list0(T value)
同样,下面的代码指出args的类型为Args:
void show_list1(Args... args) // args is a function parameter pack
更准确地说,这意味着函数参数包args包含的值列表与模板参数包Args包含的类型列表匹配——无论是类型还是数量。在上面的示例中,args包含值‘S’、80、“sweet”和4.5。
这样,可变参数模板show_list1()与下面的函数调用都匹配:
show_list1();
show_list1(99);
show_list1(88.5, "cat");
show_list1(2,4,6,8, "who do we", std::string("appreciate));
就最后一个函数调用而言,模板参数包Args包含类型int、int、int、int、const char *和std::string,而函数参数包args包含值2、4、6、8、“who do we”和std::string(“appreciate”)。