Title
Partial ordering with rewritten candidates
Status
c++20
Section
13.7.7.3 [temp.func.order]
Submitter
Hubert Tong

Created on 2020-01-29.00:00:00 last changed 47 months ago

Messages

Date: 2020-02-15.00:00:00

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 the Each function templates template M that is a member function, and that function is a non-static member of some class A, M is considered to have a new first parameter of type X(M), described below, inserted in its function parameter list. Given cv as the If 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-qualifiers of M (if any), the new parameter cv 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 the first positionally 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 parameter X(M) is of type “lvalue reference to cv A”.

[Note: This allows...

Date: 2020-02-15.00:00:00

[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; }
History
Date User Action Args
2020-12-15 00:00:00adminsetmessages: + msg6476
2020-01-29 00:00:00admincreate