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

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

: *end 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.

—
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.

- 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::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.