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

2024-12-19


2546. Defaulted secondary comparison operators defined as deleted

Section: 11.10.4  [class.compare.secondary]     Status: DRWP     Submitter: Jim X     Date: 2022-03-07

[Accepted as a DR at the March, 2024 meeting.]

(See also editorial issues 5335 and 5336.)

Consider the example in 11.10.4 [class.compare.secondary] paragraph 3:

  struct HasNoLessThan { };
  struct C {
    friend HasNoLessThan operator<=>(const C&, const C&);
    bool operator<(const C&) const = default;  // OK, function is deleted
  };

While the comment may reflect the intent, it does not follow from the wording. 11.10.4 [class.compare.secondary] paragraph 2 specifies:

The operator function with parameters x and y is defined as deleted if

Otherwise, the operator function yields x @ y. The defaulted operator function is not considered as a candidate in the overload resolution for the @ operator.

Overload resolution applied to x < y results in a usable candidate operator<=> (12.2.1 [over.match.general]) and that candidate is a rewritten candidate (12.2.2.3 [over.match.oper] bullet 3.4), thus operator< in the above example is not deleted. However, its definition is ill-formed, because the rewrite (x <=> y) < 0 is ill-formed (12.2.2.3 [over.match.oper] paragraph 8).

There is implementation divergence.

Subclause 11.10.3 [class.spaceship] paragraph 1 seems to prefer an ill-formed program for similar synthesized situations:

[Note 1: A synthesized three-way comparison is ill-formed if overload resolution finds usable candidates that do not otherwise meet the requirements implied by the defined expression. —end note]

Proposed resolution (approved by CWG 2024-03-20):

Change in 11.10.4 [class.compare.secondary] paragraph 2 as follows:
The operator function with parameters x and y is defined as deleted if

In any of the two overload resolutions above, the defaulted operator function is not considered as a candidate for the @ operator. Otherwise, the operator function yields x @ y. The defaulted operator function is not considered as a candidate in the overload resolution for the @ operator.