A defaulted comparison operator function ([expr.spaceship], [expr.rel], [expr.eq])
for some class C
shall be a non-template function
declared in the *member-specification* of C
that is

- a non-static member of C having one parameter of type const C&, or

A three-way comparison operator for a class type C
is a *structural comparison operator*
if it is defined as defaulted in the definition of C,
and all three-way comparison operators it invokes
are structural comparison operators.

A type T
has *strong structural equality*
if, for a glvalue x of type const T,
x <=> x is a valid expression
of type std::strong_ordering or std::strong_equality
and either does not invoke a three-way comparison operator
or invokes a structural comparison operator.

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 be an lvalue denoting the element
in the expanded list of subobjects for an object x
(of length n),
where 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.

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
, , …, .

[ Note

: *end note*

]Otherwise,
the program will be ill-formed
if the expression <=>
is not implicitly convertible to the declared return type for any i.

—
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
and
in the expanded lists of subobjects for x and y
until the first index i
where <=>
yields a result value where ,
contextually converted to bool, yields true;
V is converted to R.

- Otherwise, if at least one is std::weak_equality, or at least one is std::strong_equality and at least one is std::partial_ordering or std::weak_ordering, U is std::weak_equality ([cmp.weakeq]).
- Otherwise, if at least one is std::partial_ordering, U is std::partial_ordering ([cmp.partialord]).

A defaulted relational ([expr.rel]) or equality ([expr.eq]) operator function
for some operator @
shall have a declared return type bool.

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

- overload resolution ([over.match]), as applied to x <=> y (also considering synthesized candidates with reversed order of parameters ([over.match.oper])), results in an ambiguity or a function that is deleted or inaccessible from the operator function, or

Otherwise, the operator function yields
x <=> y @ 0
if an operator<=>
with the original order of parameters was selected, or
0 @ y <=> x
otherwise.