This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Resolved status.

### 3061. What is the return type of `compare_3way`?

Section: 27.8.12 [alg.three.way] Status: Resolved Submitter: Richard Smith Opened: 2018-02-07 Last modified: 2020-09-06

Priority: 2

View all other issues in [alg.three.way].

View all issues with Resolved status.

Discussion:

The P0768R1 specification of compare_3way says:

>     template<class T, class U> constexpr auto compare_3way(const T& a, const U& b);

> > -1- Effects: Compares two values and produces a result of the strongest applicable comparison category type:

> > 1. (1.1) — Returns `a <=> b` if that expression is well-formed.

> > 2. (1.2) — Otherwise, if the expressions `a == b` and `a < b` are each well-formed and convertible to `bool`, returns `strong_ordering::equal` when `a == b` is `true`, otherwise returns `strong_ordering::less` when `a < b` is `true`, and otherwise returns `strong_ordering::greater`.

> > 3. (1.3) — Otherwise, if the expression `a == b` is well-formed and convertible to `bool`, returns `strong_equality::equal` when `a == b` is `true`, and otherwise returns `strong_equality::nonequal`.

> > 4. (1.4) — Otherwise, the function shall be defined as deleted.

So, it returns `strong_ordering::...` or `strong_equality::` or `a <=> b`. By the normal core deduction rules, that means it's always ill-formed, because one return type deduction deduces `strong_ordering` and another deduces `strong_equality`.

I'm guessing the idea was actually that the above happens as if by four separate overloads / `constexpr if` / else. But I think you need to actually say that.

[Tomasz suggests proposed wording]

[2018-06-18 after reflector discussion]

Priority set to 2

[2018-11 San Diego Thursday night issue processing]

Spaceship is still in flux; revisit in Kona. Status to Open

[2020-01 Resolved by the adoption of P1614 in Cologne.]

Proposed resolution:

This wording is relative to N4713.

1. Modify 27.4 [algorithm.syn], header `<algorithm>` synopsis, as indicated:

   >     // 27.8.12 [alg.three.way], three-way comparison algorithms
   >     template<class T, class U>
   >     constexpr autosee below compare_3way(const T& a, const U& b);

2. Modify 27.8.12 [alg.three.way] as indicated:

   >     template<class T, class U> constexpr autosee below compare_3way(const T& a, const U& b);

   > > -1- Effects: Compares two values and produces a result of the strongest applicable comparison category type:

   > > 1. (1.1) — Returns `a <=> b` if that expression is well-formed If the expression `a <=> b` is well-formed, returns a value of type `decay_t<decltype(a <=> b)>` initialized from `a <=> b`.

   > > 2. (1.2) — Otherwise, if the expressions `a == b` and `a < b` are each well-formed and convertible to `bool`, returns a value of type `strong_ordering` equal to `strong_ordering::equal` when `a == b` is `true`, otherwise returns `strong_ordering::less` when `a < b` is `true`, and otherwise returns `strong_ordering::greater`.

   > > 3. (1.3) — Otherwise, if the expression `a == b` is well-formed and convertible to `bool`, returns a value of type `strong_equality` equal to `strong_equality::equal` when `a == b` is `true`, and otherwise returns `strong_equality::nonequal`.

   > > 4. (1.4) — Otherwise, the return type is `void` and the function is defined as deleted.