11 Classes [class]

11.11 Comparisons [class.compare]

11.11.3 Three-way comparison [class.spaceship]

The synthesized three-way comparison of type R ([cmp.categories]) of glvalues a and b of the same type is defined as follows:
  • If a <=> b is usable ([class.compare.default]), static_­cast<R>(a <=> b).
  • Otherwise, if overload resolution for a <=> b is performed and finds at least one viable candidate, the synthesized three-way comparison is not defined.
  • Otherwise, if R is not a comparison category type, or either the expression a == b or the expression a < b is not usable, the synthesized three-way comparison is not defined.
  • Otherwise, if R is strong_­ordering, then
    a == b ? strong_ordering::equal :
    a < b  ? strong_ordering::less :
  • Otherwise, if R is weak_­ordering, then
    a == b ? weak_ordering::equivalent :
    a < b  ? weak_ordering::less :
  • Otherwise (when R is partial_­ordering),
    a == b ? partial_ordering::equivalent :
    a < b  ? partial_ordering::less :
    b < a  ? partial_ordering::greater :
A synthesized three-way comparison may be ill-formed if overload resolution finds usable candidates that do not otherwise meet the requirements implied by the defined expression.
— end note]
Let R be the declared return type of a defaulted three-way comparison operator function, and let be the elements of the expanded list of subobjects for an object x of type C.
The return value V of type R of the defaulted three-way comparison operator function with parameters x and y of the same type is determined by comparing corresponding elements and in the expanded lists of subobjects for x and y (in increasing index order) until the first index i where the synthesized three-way comparison of type R between and yields a result value where , contextually converted to bool, yields true; V is a copy of .
If no such index exists, V is static_­cast<R>(std​::​strong_­ordering​::​equal).
The common comparison type U of a possibly-empty list of n comparison category types , , , is defined as follows:
  • If at least one is std​::​partial_­ordering, U is std​::​partial_­ordering ([cmp.partialord]).
  • Otherwise, if at least one is std​::​weak_­ordering, U is std​::​weak_­ordering ([cmp.weakord]).
  • Otherwise, U is std​::​strong_­ordering ([cmp.strongord]).
    In particular, this is the result when n is 0.
    — end note]