可变参数模板
基本语法及原理
C++11 支持可变参数模板,即支持可变数量参数的函数模板和类模板。可变数目的参数称为参数包,存在两种参数包:模板参数包(表示零或多个模板参数)和函数参数包(表示零或多个函数参数)。
template <class ...Args> void Func(Args&&... args) {}
使用省略号来指出一个模板参数或函数参数表示一个包。在模板参数列表中,class... 或 typename... 指出接下来的参数表示零或多个类型列表;在函数参数列表中,类型名后面跟 ... 指出接下来表示零或多个形参对象列表。函数参数包可以用左值引用或右值引用表示,遵循引用折叠规则。
可变参数模板的原理本质还是去实例化对应类型和个数的多个函数。可以使用 sizeof... 运算符计算参数包中参数的个数。
template <class ...Args> void Print(Args&&... args) { cout << sizeof...(args) << endl; }
int main() {
double x = 2.2;
Print(); // 包里有 0 个参数
Print(1); // 包里有 1 个参数
Print(1, string("xxxxx")); // 包里有 2 个参数
Print(1.1, string("xxxxx"), x); // 包里有 3 个参数
return 0;
}
编译本质会结合引用折叠规则实例化出对应的函数。有了可变参数模板,我们在类型泛化基础上叠加数量变化,让泛型编程更灵活。
包扩展
对于参数包,除了计算参数个数,主要操作是扩展它。扩展一个包就是将它分解为构成的元素,对每个元素应用模式,获得扩展后的列表。通过在模式的右边放一个省略号 (...) 来触发扩展操作。 C++ 还支持更复杂的包扩展,直接将参数包依次展开作为实参给一个函数处理。 不支持用下面的方式去进行包扩展(运行时无法获取解析):
< ...Args> {
cout << ...(args) << endl;
( i = ; i < ...(args); i++) {
cout << args[i] << ;
}
cout << endl;
}


