HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppCritical

What is the <=> ("spaceship", three-way comparison) operator in C++?

Submitted by: @import:stackoverflow-api··
0
Viewed 0 times
comparisonthethreewayoperatorwhatspaceship

Problem

While I was trying to learn about C++ operators, I stumbled upon the following table that listed a strange comparison operator. What does this ` operator do?

Since 2017 cppreference.com updated that page and now contains detailed information about the
`operator.

Solution

On 2017-11-11, the ISO C++ committee adopted Herb Sutter's proposal for the "spaceship" three-way comparison operator as one of the new features that were added to C++20. In the paper titled Consistent comparison Sutter, Maurer and Brown demonstrate the concepts of the new design. For an overview of the proposal, here's an excerpt from the article:

The expression a b returns an object that compares 0 if a > b, and compares ==0 if a and b are
equal/equivalent.

Common case: To write all comparisons for your type X with type Y, with memberwise semantics, just write:

auto X::operator(const Y&) const = default;


Advanced cases: To write all comparisons for your type X with type Y, just write operator that takes a Y, can use
=default to get memberwise semantics if desired, and returns the
appropriate category type:

  • Return an _ordering if your type naturally supports , =, ==, and


!=; otherwise return an _equality, and we’ll efficiently generate
symmetric == and !=.

  • Return strong_ if for your type a == b implies f(a) == f(b) (substitutability, where f reads only comparison-salient state that


is accessible using the public const members), otherwise return
weak_.

Comparison Categories

Five comparison categories are defined as std:: types,
with the following predefined values:

┌──────────────────┬───────────────────────────────────┬─────────────┐
│                  │          Numeric  values          │ Non-numeric │
│     Category     ├──────┬────────────┬───────────────┤             │
│                  │ -1   │ 0          │ +1            │   values    │
├──────────────────┼──────┼────────────┼───────────────┼─────────────┤
│ strong_ordering  │ less │ equal      │ greater       │             │
│ weak_ordering    │ less │ equivalent │ greater       │             │
│ partial_ordering │ less │ equivalent │ greater       │ unordered   │
│ strong_equality  │      │ equal      │ nonequal      │             │
│ weak_equality    │      │ equivalent │ nonequivalent │             │
└──────────────────┴──────┴────────────┴───────────────┴─────────────┘


Implicit conversions between these types are defined as follows:

  • strong_ordering with values {less, equal, greater} implicitly converts to:



  • weak_ordering with values {less, equivalent, greater}



  • partial_ordering with values {less, equivalent, greater}



  • strong_equality with values {unequal, equal, unequal}



  • weak_equality with values {nonequivalent, equivalent, nonequivalent}



  • weak_ordering with values {less, equivalent, greater} implicitly converts to:



  • partial_ordering with values {less, equivalent, greater}



  • weak_equality with values {nonequivalent, equivalent, nonequivalent}



  • partial_ordering with values {less, equivalent, greater, unordered} implicitly converts to:



  • weak_equality with values {nonequivalent, equivalent, nonequivalent, nonequivalent}



  • strong_equality with values {equal, unequal} implicitly converts to:



  • weak_equality with values {equivalent, nonequivalent}



Three-way comparison

The`token is introduced. The character sequencetokenizes to, in old source code. For example,Xneeds to add a space to retain its meaning.

The overloadable operator
is a three-way comparison function and has precedence higher thanoperators defined in the language and in the standard library return one of the 5 aforementionedstd::comparison category types.

For language types, the following built-in
same-type comparisons are provided. All are constexpr, except where noted otherwise. These comparisons cannot be invoked heterogeneously using scalar promotions/conversions.

  • Forbool, integral, and pointer types,returnsstrong_ordering.



  • For pointer types, the different cv-qualifications and derived-to-base conversions are allowed to invoke a homogeneous built-in, and there are built-in heterogeneousoperator(T*, nullptr_t). Only comparisons of pointers to the same object/allocation are constant expressions.



  • For fundamental floating point types, returnspartial_ordering, and can be invoked heterogeneously by widening arguments to a larger floating point type.



  • For enumerations, returns the same as the enumeration's underlying type's.



  • Fornullptr_t, returnsstrong_orderingand always yieldsequal.



  • For copyable arrays,T[N] T[N]returns the same type asT'sand performs lexicographical elementwise comparison. There is nofor other arrays.



  • Forvoidthere is no`.



To better understand the inner workings of this operator, please read the original paper. This is just what I've found out using search engines. Also, check out Comparison Operators, including Three-Way Comparison(C++20).

Code Snippets

auto X::operator<=>(const Y&) const = default;
┌──────────────────┬───────────────────────────────────┬─────────────┐
│                  │          Numeric  values          │ Non-numeric │
│     Category     ├──────┬────────────┬───────────────┤             │
│                  │ -1   │ 0          │ +1            │   values    │
├──────────────────┼──────┼────────────┼───────────────┼─────────────┤
│ strong_ordering  │ less │ equal      │ greater       │             │
│ weak_ordering    │ less │ equivalent │ greater       │             │
│ partial_ordering │ less │ equivalent │ greater       │ unordered   │
│ strong_equality  │      │ equal      │ nonequal      │             │
│ weak_equality    │      │ equivalent │ nonequivalent │             │
└──────────────────┴──────┴────────────┴───────────────┴─────────────┘

Context

Stack Overflow Q#47466358, score: 181

Revisions (0)

No revisions yet.