可变参数模板 - 参数包扩展理解

Jam*_*nco 6 c++ templates variadic-templates c++11

我很难理解参数包扩展。让我困惑的是点何时出现在右侧以及何时点出现在左侧。我发现这篇文章对我有一点帮助。假设我有以下两个例子

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);
}
Run Code Online (Sandbox Code Playgroud)

我相信我上面提到的帖子提到了黑白差异...A,并且A...第一个帖子进行左侧扩展,第二个帖子进行右侧扩展。我不确定这意味着什么。谁能澄清一下扩展后的样子。到目前为止,我唯一了解的关于右侧点的例子是这样的

//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
Run Code Online (Sandbox Code Playgroud)

谁能澄清一下第 1 行和第 2 行中的点扩展到什么以及左侧扩展和右侧扩展之间有什么区别?

Bar*_*rry 5

没有“左侧扩展”,只有“右侧扩展”。当您输入:

template <class ...A>
int func(A... arg)
Run Code Online (Sandbox Code Playgroud)

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

 template <class... A>
Run Code Online (Sandbox Code Playgroud)

如,A命名一个由 es 组成的参数包class。该行中没有进行任何扩展 - 它只是声明函数模板的参数是什么func

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

template <typename... T>
void foo(T (*...fs)());
Run Code Online (Sandbox Code Playgroud)

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

至于参数包扩展,请参阅我的回答此处,获取参数扩展根据放置执行的操作的示例列表...。简短的版本是:紧接在 之前的表达式中的所有包...同时展开。您在问题中列出的所有示例都是正确的。我还想补充一点:

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), ...
Run Code Online (Sandbox Code Playgroud)

  • 不过,了解在“A ...args”中,“...”作为语法问题绑定到“args”是很有用的。除非您知道这一点,否则一些更疯狂的声明符没有多大意义。 (3认同)