Files
cppdraft_translate/cppdraft/expr/spaceship.md
2025-10-25 03:02:53 +03:00

5.7 KiB
Raw Permalink Blame History

[expr.spaceship]

7 Expressions [expr]

7.6 Compound expressions [expr.compound]

7.6.8 Three-way comparison operator [expr.spaceship]

1

#

The three-way comparison operator groups left-to-right.

compare-expression:
shift-expression
compare-expression <=> shift-expression

2

#

The expression p <=> q is a prvalue indicating whetherp is less than, equal to, greater than, or incomparable withq.

3

#

If one of the operands is of type bool and the other is not, the program is ill-formed.

4

#

If both operands have arithmetic types, or one operand has integral type and the other operand has unscoped enumeration type, the usual arithmetic conversions are applied to the operands.

Then:

  • (4.1)

    If a narrowing conversion is required, other than from an integral type to a floating-point type, the program is ill-formed.

  • (4.2)

    Otherwise, if the operands have integral type, the result is of type std::strong_ordering. The result isstd::strong_ordering::equal if both operands are arithmetically equal,std::strong_ordering::less if the first operand is arithmetically less than the second operand, andstd::strong_ordering::greater otherwise.

  • (4.3)

    Otherwise, the operands have floating-point type, and the result is of type std::partial_ordering. The expression a <=> b yieldsstd::partial_ordering::less if a is less than b,std::partial_ordering::greater if a is greater than b,std::partial_ordering::equivalent if a is equivalent to b, andstd::partial_ordering::unordered otherwise.

5

#

If both operands have the same enumeration type E, the operator yields the result of converting the operands to the underlying type of E and applying <=> to the converted operands.

6

#

If at least one of the operands is of object pointer type and the other operand is of object pointer or array type, array-to-pointer conversions ([conv.array]), pointer conversions ([conv.ptr]), andqualification conversions are performed on both operands to bring them to their composite pointer type ([expr.type]).

After the conversions, the operands shall have the same type.

[Note 1:

If both of the operands are arrays,array-to-pointer conversions are not applied.

— end note]

In this case,p <=> q is of type std::strong_ordering and the result is defined by the following rules:

If two pointer operands p and q compare equal ([expr.eq]),p <=> q yields std::strong_ordering::equal;

otherwise, if p and q compare unequal,p <=> q yieldsstd::strong_ordering::less if q compares greater than p andstd::strong_ordering::greater if p compares greater than q ([expr.rel]);

otherwise, the result is unspecified.

7

#

Otherwise, the program is ill-formed.

8

#

The three comparison category types ([cmp.categories]) (the typesstd::strong_ordering,std::weak_ordering, andstd::partial_ordering) are not predefined; if a standard library declaration ([compare.syn], [std.modules]) of such a class type does not precede ([basic.lookup.general]) a use of that type — even an implicit use in which the type is not named (e.g., via the auto specifier ([dcl.spec.auto]) in a defaulted three-way comparison ([class.spaceship]) or use of the built-in operator) — the program is ill-formed.