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

**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) — Returns

a <=> bif that expression is well-formed.(1.2) — Otherwise, if the expressions

a == banda < bare each well-formed and convertible tobool, returnsstrong_ordering::equalwhena == bistrue, otherwise returnsstrong_ordering::lesswhena < bistrue, and otherwise returnsstrong_ordering::greater.(1.3) — Otherwise, if the expression

a == bis well-formed and convertible tobool, returnsstrong_equality::equalwhena == bistrue, and otherwise returnsstrong_equality::nonequal.(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.

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~~auto~~*see below*compare_3way(const T& a, const U& b);Modify 27.8.12 [alg.three.way] as indicated:

template<class T, class U> constexpr

~~auto~~*see 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) —

~~Returns~~If the expression`a <=> b`if that expression is well-formed`a <=> b`is well-formed, returns a value of type`decay_t<decltype(a <=> b)>`initialized from`a <=> b`.(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`.(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`.(1.4) — Otherwise, the return type is

`void`and the function is defined as deleted.