10 Classes [class]

10.10 Comparisons [class.compare]

10.10.2 Three-way comparison [class.spaceship]

The direct base class subobjects of C, in the order of their declaration in the base-specifier-list of C, followed by the non-static data members of C, in the order of their declaration in the member-specification of C, form a list of subobjects.
In that list, any subobject of array type is recursively expanded to the sequence of its elements, in the order of increasing subscript.
Let x be an lvalue denoting the element in the expanded list of subobjects for an object x (of length n), where x is formed by a sequence of derived-to-base conversions ([over.best.ics]), class member access expressions ([expr.ref]), and array subscript expressions ([expr.sub]) applied to x.
The type of the expression x <=> x is denoted by R.
It is unspecified whether virtual base class subobjects are compared more than once.
If the declared return type of a defaulted three-way comparison operator function is auto, then the return type is deduced as the common comparison type (see below) of R, R, , R.
[Note
:
Otherwise, the program will be ill-formed if the expression x <=> x is not implicitly convertible to the declared return type for any i.
end note
]
If the return type is deduced as void, the operator function is defined as deleted.
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 x and y in the expanded lists of subobjects for x and y until the first index i where x <=> y yields a result value v where v, contextually converted to bool, yields true; V is v converted to R.
If no such index exists, V is std::strong_­ordering::equal converted to R.
The common comparison type U of a possibly-empty list of n types T, T, , T is defined as follows:
  • If any T is not a comparison category type ([cmp.categories]), U is void.
  • Otherwise, if at least one T is std::weak_­equality, or at least one T is std::strong_­equality and at least one T is std::partial_­ordering or std::weak_­ordering, U is std::weak_­equality ([cmp.weakeq]).
  • Otherwise, if at least one T is std::strong_­equality, U is std::strong_­equality ([cmp.strongeq]).
  • Otherwise, if at least one T is std::partial_­ordering, U is std::partial_­ordering ([cmp.partialord]).
  • Otherwise, if at least one T is std::weak_­ordering, U is std::weak_­ordering ([cmp.weakord]).
  • Otherwise, U is std::strong_­ordering ([cmp.strongord]).
    [Note
    :
    In particular, this is the result when n is 0.
    end note
    ]