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]) and can be explicitly converted to R using static_cast, 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 : strong_ordering::greater
- Otherwise, if R is weak_ordering, then a == b ? weak_ordering::equivalent : a < b ? weak_ordering::less : weak_ordering::greater
- Otherwise (when R is partial_ordering), a == b ? partial_ordering::equivalent : a < b ? partial_ordering::less : b < a ? partial_ordering::greater : partial_ordering::unordered

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 operator function is defined as deleted if that expression is not usable or if is not a comparison category type ([cmp.categories.pre]) for any i.

The return value 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.

The return value is a copy of
if such an index exists and
static_cast<R>(std::strong_ordering::equal) otherwise.

The *common comparison type* U
of a possibly-empty list of n comparison category types
, , …,
is defined as follows: