In resolving ambiguities between function template overloads, partial ordering is performed (see here for some explanations). In that website, we also learn that
In case of a tie, if one function template has a trailing parameter pack and the other does not, the one with the omitted parameter is considered to be more specialized than the one with the empty parameter pack.
Now, I wonder what precisely a trailing parameter pack is. Which if any of
template<class ...> struct tuple { /* ... */ };
template<class T, class...Ts> void foo(tuple<T,Ts...>);
template<class T, class...Ts> void bar(T, Ts...);
is and which not and why? Note also that clang considers
template<class T> void f(tuple<T>);
template<class T, class...Ts> void f(tuple<T,Ts...>);
int main()
{ f(tuple<int>()); } // ambiguous call?
ambiguous, implying that foo
does not have a trailing parameter pack.
Trailing means "at the end of".
A trailing parameter pack is a parameter pack found at the end of a list of template parameters:
This is not a C++ question, but an English question.
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]:
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:
Or, a function parameter pack that appears as the rightmost parameter in a function parameter list:
The current draft still contains this outdated example in [temp.deduct.type]:
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:
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 templateC
in the following example: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.