This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115f. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-12-06
[Accepted at the February, 2020 (Prague) meeting.]
The tiebreaker based on partial ordering of function templates should presumably operate upon rewritten candidates based on their parameter lists for the purpose of overload resolution (12.2.2 [over.match.funcs]) without substitution of template arguments instead of the function parameter lists of the templates themselves.
It is observed, however, that neither GCC nor Clang performs partial ordering in the manner described above. In the following case, considering the templates with the reordering should yield 1a as being more specialized than 2; however, the wording is not especially clear about this and both GCC and Clang seems to fall past the partial ordering tiebreaker to pick 2 for the case as-is. If 1b is introduced, then it is more specialized than 2 in either ordering, and it is chosen by both GCC and Clang.
template <typename> constexpr bool F = false; template <typename T> struct A { }; template <typename T, typename U> // bool operator==(A<T>, A<U *>); // 1b bool operator==(T, A<U *>); // 1a template <typename T, typename U> bool operator!=(A<T>, U) { // 2 static_assert(F<T>, "Isn't this less specialized?"); return false; } bool f(A<int> ax, A<int *> ay) { return ay != ax; }
Proposed resolution (February, 2020):
Change 13.7.7.3 [temp.func.order] paragraph 3 as follows:
To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs (13.7.4 [temp.variadic]) thereof) synthesize a unique type, value, or class template respectively and substitute it for each occurrence of that parameter in the function type of the template. [Note: The type replacing the placeholder in the type of the value synthesized for a non-type template parameter is also a unique synthesized type. —end note]
If only one of theEach functiontemplatestemplate M that is a member function, and that function is a non-static member of some class A, Mis considered to have a new first parameter of type X(M), described below, inserted in its function parameter list.Given cv as theIf exactly one of the function templates was considered by overload resolution via a rewritten candidate (12.2.2.3 [over.match.oper]) with a reversed order of parameters, then the order of the function parameters in its transformed template is reversed. For a function template M with cv-qualifiersof M (if any), the new parametercv that is a member of a class A:
The type X(M) is
of type“rvalue reference to cv A” if the optional ref-qualifier of M is && or if M has no ref-qualifier and thefirstpositionally corresponding parameter of the other transformed template has rvalue reference type; if this determination depends recursively upon whether X(M) is an rvalue reference type, it is not considered to have rvalue reference type.Otherwise,
the new parameterX(M) isof type“lvalue reference to cv A”.[Note: This allows...