What exactly is a “trailing parameter pack”

拥有回忆 提交于 2019-12-03 06:12:37

This is CWG1395, for which a defect resolution was recently voted in to the draft C++17 standard. The following was added to [temp.deduct.partial]:

...[if] function template F is at least as specialized as function template G and vice-versa, and if G has a trailing parameter pack for which F does not have a corresponding parameter, and if F does not have a trailing parameter pack, then F is more specialized than G.

The standard doesn't explicitly define what it means by "trailing parameter pack", but judging by the existing contexts in which this term is used, it refers to a template parameter pack that appears as the rightmost parameter in a template parameter list:

template<class T, class... U> struct X;
//                ^^^^^^^^^^

Or, a function parameter pack that appears as the rightmost parameter in a function parameter list:

template<class T, class... U> void y(T, U...);
//                                      ^^^^

The current draft still contains this outdated example in [temp.deduct.type]:

template<class T, class... U> void f(T, U...);
template<class T> void f(T);

f(&i); // error: ambiguous

This standard defect report has been around for a few years, and both GCC and Clang have implemented resolutions of it. They both agree that the example above is a valid call of the second overload of f.

Where GCC and Clang disagree is on the scope of the defect resolution. This is understandable, as it was only recently updated to include proposed standard wording. In your example, the pack is not expanded into the function parameter list, but into the template argument list of a function parameter type:

template<class T, class... U> void g(tuple<T, U...>);
template<class T> void g(tuple<T>);

g(tuple<int>{});

GCC treats this as a valid call of the second overload of g; Clang treats it as ambiguous. The correctness of Clang may depend on whether "trailing parameter pack" is intended to include trailing template parameter packs, or only trailing function parameter packs.

Note that both compilers agree that C<int> refers to the second partial specialization of the class template C in the following example:

template<class...> struct C;

template<class T, class... U> struct C<T, U...> {};
template<class T> struct C<T> {};

This seems like an inconsistency in Clang, because the standard rules for partial ordering of class template specializations is defined in terms of partial ordering of function templates. See CWG1432.

Trailing means "at the end of".

A trailing parameter pack is a parameter pack found at the end of a list of template parameters:

template <typename T1, typename... Ts>
void foo();

// ^ Ts... is trailing here

This is not a C++ question, but an English question.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!