Variadic模板 - 参数包扩展理解

时间:2015-07-27 17:42:48

标签: c++ templates c++11 variadic-templates

我很难理解参数包扩展。 令我困惑的是当点出现在右侧并且点出现在左侧时。我偶然发现了this帖子。 假设我有以下两个例子

Example 1:
template <class ...A>   --> line 1
int func(A... arg)      --> line 2
{
   return sizeof...(arg);
}

int main(void)
{
   return func(1,2,3,4,5,6);
}

我上面提到的帖子我相信提到差异b / w ...AA...是第一个做左侧扩展而第二个做右侧扩展。我不确定这意味着什么。任何人都可以通过扩展时的样子来澄清这一点。到目前为止,我唯一理解的右侧点是像

这样的例子
//Foo and bar are variadic parameter packs
Foo...                     => Foo1, Foo2, Foo3, etc
std::vector<Foo>...        => std::vector<Foo1>, std::vector<Foo2>, std::vector<Foo3>, etc.
std::tuple<Foo...>(bar...) => std::tuple<Foo1, Foo2, Foo3, etc>(bar1, bar2, bar3, etc)
&bar...                    => &bar1, &bar2, &bar3, etc

任何人都可以澄清第1行和第2行的点扩展到什么,左侧扩展和右侧扩展有什么区别?

1 个答案:

答案 0 :(得分:2)

没有“左侧扩张”,只有“右侧扩张”。当你输入:

template <class ...A>
int func(A... arg)

...不适用于A。它有助于将其视为:

 template <class... A>

同样,A命名由class es组成的参数包。该行没有扩展 - 它只是声明函数模板func的参数。

此外,正如T.C.指出的那样,参数列表中的...在语法上会绑定参数名称而不是其类型。这有助于理解特别复杂的声明,例如:

template <typename... T>
void foo(T (*...fs)());

其中fs将是一个(可能是空的)指向nullary函数的指针包。

对于参数包扩展,请参阅我的回答here,以获取基于...展示位置参数扩展的示例列表。简短版本是:...之前的表达式中的所有包同时展开。您在问题中列出的所有示例都是正确的。我还要补充一下:

std::tuple<Foo...>(bar...) => std::tuple<Foo1, Foo2, Foo3, etc>(bar1, bar2, bar3, etc)
std::tuple<Foo>(bar)...    => std::tuple<Foo1>(bar1), std::tuple<Foo2>(bar2), ...