
Last year, I specifically introduced the extremely rare C++ syntax <span>......</span> in the article “What does the …… mean in C++?” which is actually an abbreviated syntax for <span>..., ...</span>.
The following three forms are completely equivalent:
template<class... Args> void f(Args......) {}
template<class... Args> void f(Args... ...) {}
template<class... Args> void f(Args..., ...) {}
The first <span>...</span> is used to expand C++ variadic template parameters, while the second <span>...</span> is used to match the old-style variadic functions in C.
The complete usage and examples have been detailed in the original text, which can be read by following the link at the bottom of the article. (Click on the “Read Original” at the bottom of the article to be redirected.)
By C++26, the first two forms will be deprecated, and the comma can no longer be omitted. The main reasons are twofold: first, it will affect any future proposals attempting to use the syntax <span>int...</span>; second, many users interpret <span>int...</span> as a template parameter pack rather than Ellipsis Parameters, leading to confusion and misuse.
After deprecation, the syntax rule becomes:
parameter-declaration-clause:
parameter-declaration-listopt …opt… parameter-declaration-listopt parameter-declaration-list , …
Thus, using <span>int...</span> (generically) as an equivalent to <span>int, ...</span> has become illegal. For example:
void f(int...); // deprecated
void f(int x...); // deprecated
void g(auto...); // OK, declares a function parameter pack
void h(auto......); // deprecated
template<class... Ts> void a(Ts...); // OK, function template parameter pack
Here are two similar but semantically different examples:
// abbreviated variadic function template
void g(auto ...args);
// abbreviated non-variadic function template with ellipsis parameter
void g(auto args...);
The second usage has now been deprecated.
By the way, previously <span>T...</span> could be interpreted as either a template parameter pack or as <span>T</span> followed by an Ellipsis Parameter. The reason there was no ambiguity is that the compiler would prioritize interpreting it as a template parameter pack. Now only the first interpretation remains, eliminating any ambiguity.
The specifier <span>...</span> is still valid, maintaining compatibility with C. In short, the following two forms still represent Ellipsis Parameters:
// OK, ellipsis parameters, compatible with C
void f(...);
void g(int, ...);