Title
Missing entry in Annex C for defaulted comparison operators
Status
dr
Section
Clause [Annex] C [diff]
Submitter
Tomasz Kaminski

Created on 2019-02-26.00:00:00 last changed 1 week ago

Messages

Date: 2022-11-10.15:23:57

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
Date: 2019-04-15.00:00:00

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
Date: 2019-03-15.00:00:00

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.

Date: 2022-11-15.00:00:00

[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!=.

History
Date User Action Args
2022-11-25 05:14:04adminsetstatus: ready -> dr
2022-11-10 22:04:48adminsetstatus: review -> ready
2022-11-10 22:04:48adminsetstatus: review -> review
2022-11-10 22:04:48adminsetstatus: review -> review
2022-11-10 22:04:48adminsetstatus: review -> review
2022-11-10 15:23:57adminsetstatus: ready -> review
2022-11-10 15:23:57adminsetstatus: ready -> ready
2022-11-10 15:23:57adminsetstatus: ready -> ready
2022-11-10 15:23:57adminsetmessages: + msg6996
2020-12-15 00:00:00adminsetmessages: + msg6227
2020-12-15 00:00:00adminsetmessages: + msg6226
2019-02-26 00:00:00admincreate