This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 114a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.

2024-04-18


2524. Distinguishing user-defined conversion sequences by ref-qualifier

Section: 12.2.4.3  [over.ics.rank]     Status: NAD     Submitter: Hani Deek     Date: 2021-09-09

Consider the following example:

  struct S  {
      operator int() const & { return 0; }
      operator char() && { return 0; }
  };

  void foo(int) {}
  void foo(char) {}

  int main() {
    foo(S{}); //OK, calls foo(char)
  }

Here, the ICS for each function is a user-defined conversion involving the same user-defined conversion function, operator char() &&, because of 12.2.4.3 [over.ics.rank] bullet 3.2.3:

S1 and S2 include reference bindings (9.4.4 [dcl.init.ref]) and neither refers to an implicit object parameter of a non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to an rvalue and S2 binds an lvalue reference

foo(int) is a promotion, while foo(char) is an exact match, so the latter is chosen.

Replacing int and char in this example with non-interconvertible types results in a different outcome:

  class A{};
  class B{};

  struct S {
    operator A() const & { return A{}; }
    operator B() && { return B{}; }
  };

  void foo(A) {}
  void foo(B) {}

  int main() {
    foo(S{}); //error: call to foo is ambiguous
  }

Here, only one of the two user-defined conversion operators is viable for each overload. Consequently, 12.2.4.3 [over.ics.rank] bullet 3.3,

User-defined conversion sequence U1 is a better conversion sequence than another user-defined conversion sequence U2 if they contain the same user-defined conversion function or constructor or they initialize the same class in an aggregate initialization and in either case the second standard conversion sequence of U1 is better than the second standard conversion sequence of U2.

does not apply, unlike the earlier case, because different user-defined conversion functions appear in each conversion sequence and thus the sequences are indistinghishable.

This seems inconsistent.

Suggested resolution:

Change 12.2.4.3 [over.ics.rank] bullet 3.3 as follows:

CWG 2022-11-11

This is an extension that is best addressed by a paper to EWG.