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

125 lines
5.7 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[expr.spaceship]
# 7 Expressions [[expr]](./#expr)
## 7.6 Compound expressions [[expr.compound]](expr.compound#expr.spaceship)
### 7.6.8 Three-way comparison operator [expr.spaceship]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7283)
The three-way comparison operator groups left-to-right[.](#1.sentence-1)
[compare-expression:](#nt:compare-expression "7.6.8Three-way comparison operator[expr.spaceship]")
[*shift-expression*](expr.shift#nt:shift-expression "7.6.7Shift operators[expr.shift]")
[*compare-expression*](#nt:compare-expression "7.6.8Three-way comparison operator[expr.spaceship]") <=> [*shift-expression*](expr.shift#nt:shift-expression "7.6.7Shift operators[expr.shift]")
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7296)
The expression p <=> q is a prvalue indicating whetherp is less than, equal to, greater than, or incomparable withq[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7301)
If one of the operands is of type bool and the other is not, the program is ill-formed[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7305)
If both operands have arithmetic types,
or one operand has integral type and
the other operand has unscoped enumeration type,
the [usual arithmetic conversions](expr.arith.conv "7.4Usual arithmetic conversions[expr.arith.conv]") are applied to the operands[.](#4.sentence-1)
Then:
- [(4.1)](#4.1)
If a [narrowing conversion](dcl.init.list#def:conversion,narrowing "9.5.5List-initialization[dcl.init.list]") is required,
other than from an integral type to a floating-point type,
the program is ill-formed[.](#4.1.sentence-1)
- [(4.2)](#4.2)
Otherwise, if the operands have integral type,
the result is of type std::strong_ordering[.](#4.2.sentence-1)
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.2.sentence-2)
- [(4.3)](#4.3)
Otherwise, the operands have floating-point type, and
the result is of type std::partial_ordering[.](#4.3.sentence-1)
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[.](#4.3.sentence-2)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7343)
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[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7349)
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]](conv.array "7.3.3Array-to-pointer conversion")),
pointer conversions ([[conv.ptr]](conv.ptr "7.3.12Pointer conversions")),
and[qualification conversions](conv.qual "7.3.6Qualification conversions[conv.qual]") are performed on both operands
to bring them to their composite pointer type ([[expr.type]](expr.type "7.2.2Type"))[.](#6.sentence-1)
After the conversions, the operands shall have the same type[.](#6.sentence-2)
[*Note [1](#note-1)*:
If both of the operands are arrays,[array-to-pointer conversions](conv.array "7.3.3Array-to-pointer conversion[conv.array]") are not applied[.](#6.sentence-3)
— *end note*]
In this case,p <=> q is of type std::strong_ordering and
the result is defined by the following rules:
- [(6.1)](#6.1)
If two pointer operands p and q compare equal ([[expr.eq]](expr.eq "7.6.10Equality operators")),p <=> q yields std::strong_ordering::equal;
- [(6.2)](#6.2)
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]](expr.rel "7.6.9Relational operators"));
- [(6.3)](#6.3)
otherwise, the result is unspecified[.](#6.sentence-4)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7382)
Otherwise, the program is ill-formed[.](#7.sentence-1)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/expressions.tex#L7385)
The three comparison category types ([[cmp.categories]](cmp.categories "17.12.2Comparison category types"))
(the typesstd::strong_ordering,std::weak_ordering, andstd::partial_ordering)
are not predefined;
if a standard library declaration ([[compare.syn]](compare.syn "17.12.1Header <compare> synopsis"), [[std.modules]](std.modules "16.4.2.4Modules"))
of such a class type does not precede ([[basic.lookup.general]](basic.lookup.general "6.5.1General"))
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]](dcl.spec.auto "9.2.9.7Placeholder type specifiers"))
in a defaulted three-way comparison ([[class.spaceship]](class.spaceship "11.10.3Three-way comparison"))
or use of the built-in operator) — the program is ill-formed[.](#8.sentence-1)