以下内容摘自Andrei Alexandrescu在GoingNative 2012上的演讲“可变参数模板是Funadic”。我可以推荐它作为可变参数模板的良好介绍。
一个可变参数包可以做两件事。可以申请sizeof...(vs)
获取元素数量并进行扩展。
扩充规则
Use Expansion
Ts... T1, ..., Tn
Ts&&... T1&&, ..., Tn&&
x<Ts,Y>::z... x<T1,Y>::z, ..., x<Tn,Y>::z
x<Ts&,Us>... x<T1&,U1>, ..., x<Tn&,Un>
func(5,vs)... func(5,v1), ..., func(5,vn)
扩展向内向外扩展。锁定步骤扩展两个列表时,它们的大小必须相同。
更多示例:
gun(A<Ts...>::hun(vs)...);
展开Ts
的模板参数列表中的all ,A
然后hun
使用all扩展功能vs
。
gun(A<Ts...>::hun(vs...));
展开Ts
的模板参数列表中的A
全部和全部vs
作为的函数参数hun
。
gun(A<Ts>::hun(vs)...);
hun
通过Ts
和vs
逐步扩展功能。
注意:
Ts
不是类型,vs
也不是价值!它们是类型/值列表的别名。这两个列表都可能为空。两者都服从特定的动作。因此,以下操作是不可能的:
typedef Ts MyList; // error!
Ts var; // error!
auto copy = vs; // error!
扩展基因座
函数参数
template <typename... Ts>
void fun(Ts... vs)
初始化列表
any a[] = { vs... };
基本说明符
template <typename... Ts>
struct C : Ts... {};
template <typename... Ts>
struct D : Box<Ts>... { /**/ };
成员初始化器列表
// Inside struct D
template <typename... Us>
D(Us... vs) : Box<Ts>(vs)... {}
临时参数列表
std::map<Ts...> m;
仅在参数可能匹配时才编译。
捕获列表
template <class... Ts> void fun(Ts... vs) {
auto g = [&vs...] { return gun(vs...); }
g();
}
属性列表
struct [[ Ts... ]] IAmFromTheFuture {};
它在规范中,但是还没有可以表示为类型的属性。
...
出现在标识符之前。当使用其中一种或两种类型的背包时,...
表达式模式之后会出现来扩展。