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

2023-01-15


2407. Missing entry in Annex C for defaulted comparison operators

Section: Clause Annex C  [diff]     Status: DR     Submitter: Tomasz Kaminski     Date: 2019-02-26

[Accepted as a DR at the November, 2022 meeting.]

The changes from P1185R2 need an entry in Annex C, because they affect the interpretation of existing well-formed code. For example, given:

  struct A {
    operator int() const { return 10; }
  };

  bool operator==(A, int); // #1
  //built-in: bool operator==(int, int); // #2

  A a, b;

The expression 10 == a resolves to #2 in C++17 but now to #1. In addition, a == b is now ambiguous, because #1 has a user-defined conversion on the second argument, while the reversed order has it on the first argument. Similarly for operator!=.

Notes from the March, 2019 teleconference:

The ambiguity in 10 == a arises from the consideration of the reverse ordering of the operands.

CWG found this breakage surprising and asked for EWG's opinion before updating Annex C.

Proposed resolution (April, 2019) [SUPERSEDED]

Add the following as a new subclause in C.2 [diff.cpp17]:

C.5.6 Clause 12: Overloading

Affected subclause: 12.2.2.3 [over.match.oper]
Change: Overload resolution may change for equality operators 7.6.10 [expr.eq].
Rationale: Support calling operator== with reversed order of arguments.
Effect on original feature: Valid C++ 2017 code that uses equality operators with conversion functions may be ill-formed or have different semantics in this International Standard.

  struct A {
    operator int() const { return 10; }
  };

  bool operator==(A, int);               // #1
  // built-in: bool operator==(int, int);  // #2
  bool b = 10 == A();                   // uses #1 with reversed order of arguments; previously used #2

Proposed resolution:

Add the following as a new subclause in C.2 [diff.cpp17]:

C.5.6 Clause 12: Overloading

Affected subclause: 12.2.2.3 [over.match.oper]
Change: Overload resolution may change for equality operators 7.6.10 [expr.eq].
Rationale: Support calling operator== with reversed order of arguments.
Effect on original feature: Valid C++ 2017 code that uses equality operators with conversion functions may be ill-formed or have different semantics in this International Standard.

  struct A {
    operator int() const { return 10; }
  };

  bool operator==(A, int);               // #1
  // built-in: bool operator==(int, int);   // #2
  bool b = 10 == A();                   // uses #1 with reversed order of arguments; previously used #2

  struct B {
    bool operator==(const B&);          // member function with no cv-qualifier
  };
  B b1;
  bool eq = (b1 == b1);                   // ambiguous; previously well-formed