5.7 KiB
[expr.spaceship]
7 Expressions [expr]
7.6 Compound expressions [expr.compound]
7.6.8 Three-way comparison operator [expr.spaceship]
The three-way comparison operator groups left-to-right.
compare-expression:
shift-expression
compare-expression <=> shift-expression
The expression p <=> q is a prvalue indicating whetherp is less than, equal to, greater than, or incomparable withq.
If one of the operands is of type bool and the other is not, the program is ill-formed.
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:
-
If a narrowing conversion is required, other than from an integral type to a floating-point type, the program is ill-formed.
-
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.
-
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.
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.
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.
Otherwise, the program is ill-formed.
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.