摘要:到了 C++26,前两种写法被弃用,逗号不再可以省略。原因主要有两点:一是会对未来任何试图使用 int... 这种语法的提案产生影响;二是许多用户把 int... 理解为一个模板参数包,而非 Ellipsis Parameters(省略符参数),容易造成困惑和
...... 这种极其罕见的 C++ 语法,它其实是 ..., ... 的省略语法。
以下这三种写法其实完全等价:
template void f(Args......) {}template void f(Args... ...) {}template void f(Args..., ...) {}第一个 ... 用于扩展 C++ 可变模板参数包,而第二个 ... 用于匹配 C 语言中 Variadic functions 的旧式变参。
完整的用法及实例在原文中已经详细讲述,没有读过的可以移步阅读。(点击文章底部的阅读原文,可以自动跳转。)
到了 C++26,前两种写法被弃用,逗号不再可以省略。原因主要有两点:一是会对未来任何试图使用 int... 这种语法的提案产生影响;二是许多用户把 int... 理解为一个模板参数包,而非 Ellipsis Parameters(省略符参数),容易造成困惑和误用。
弃用后,语法规则变为:
parameter-declaration-clause:parameter-declaration-listopt ...opt
...
parameter-declaration-listopt
parameter-declaration-list , ...
于是,以 int...(泛指)作为 int, ... 等价用法的行为全部变得非法。例如:
void f(int...); // deprecatedvoid f(int x...); // deprecatedvoid g(auto...); // OK, declares a function parameter packvoid h(auto......); // deprecatedtemplate void a(Ts...); // OK, function template parameter pack还有下面这两个语法相近却意义不同的例子:
// abbreviated variadic function templatevoid g(auto ...args);// abbreviated non-variadic function template with ellipsis parametervoid g(auto args...);第二个用法如今已被弃用。
顺便提一下,之前 T... 既可以被解释为模板参数包,也可以被解释为 T 紧跟着一个 Ellipsis Parameter。之所以未曾出现歧义,是因为编译器会优先将其解释为模板参数包。如今只剩下第一种解释,完全不会出现歧义。
说明符 ... 依旧是合法的,与 C 中的行为保持兼容。简言之,下面这两种写法仍然表示 Ellipsis Parameters:
// OK, ellipsis parameters, compatible with Cvoid f(...);void g(int, ...);来源:不秃头程序员一点号