当省略号位于模式的最内层元素上时,在可变参数模板中打包扩展

rhl*_*ini 5 c++ templates variadic-templates c++11

我在cppreference.com上看到了这个例子.我不清楚函数参数的包扩展.

功能参数列表

在函数参数列表中,如果省略号出现在参数声明中(无论它是否命名函数参数包(如,Args ... args))参数声明是模式:

template<typename ...Ts> void f(Ts...) {}
f('a', 1);  // Ts... expands to void f(char, int)
f(0.1);     // Ts... expands to void f(double)

template<typename ...Ts, int... N> void g(Ts (&...)[N]) {}
int n[1];
g<const char, int>("a", n); // Ts (&...)[N] expands to const char (&)[2], int(&)[1]
Run Code Online (Sandbox Code Playgroud)

注意:在此模式中,省略号是最内层元素,而不是所有其他包扩展中的最后一个元素.

Yak*_*ont 8

有效:

template<typename ...Ts, int... N> void g(Ts (&...array)[N]) {}
int n[1];
g<const char, int>("a", n); // Ts (&...)[N] expands to const char (&)[2], int(&)[1]
Run Code Online (Sandbox Code Playgroud)

但是如果你跳过这个名字,显然很多编译器都有问题array.我不知道这是编译器还是标准的怪癖(两者都是合理的:这是一个严重的角点语法).

正如@Xeo所指出的,处理C的声明语法的一种不那么迟钝的方法是欺骗我们绕过这个问题:

template<typename T> using Type = T;
template<typename... Ts, int... N> void g( Type<Ts[N]>&... ) {}
Run Code Online (Sandbox Code Playgroud)

更容易解析并且不需要(至少一些)编译器具有变量名称.

  • 存在相关缺陷[CWG 1234](http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1234); 我认为语法不允许它:*declarator-id*中的`...`需要一个*id-expression*,而*noptr-abstract-pack-declarator*中的`...`不能据我所知,在括号内.也就是说,*noptr-abstract-declarator*缺少对应物:`(`*ptr-abstract-declarator*`)` (4认同)