C++20 introduces the three-way comparison operator (also known as the spaceship operator), written as <=>. It simplifies and unifies comparison operations.
Basic Concepts
The <=> operator performs a comparison between two values in one operation and returns one of three possible results:
- less -
(a <=> b) < 0ifa < b - equal/equivalent -
(a <=> b) == 0ifaandbare equal/equivalent - greater -
(a <=> b) > 0ifa > b
Return Types
It returns a value representing the comparison result, which can be directly used for sorting and equality checking.
<=> returns one of the following three types:
std::strong_ordering- Strong ordering- Values:
less,equal,greater - Applicable to: integers, pointers, etc.
- Values:
std::weak_ordering- Weak ordering- Values:
less,equivalent,greater - Applicable to: case-insensitive string comparisons
- Values:
std::partial_ordering- Partial ordering- Values:
less,equivalent,greater,unordered - Applicable to: floating-point numbers (due to NaN)
- Values:
Motivation
When first encountering the <=> operator, you might be confused about its purpose, use cases, and other questions.
Before C++20, to compare custom types, we typically had to do this:
| |
That is, we needed to implement 6 comparison operators to enable comparison of custom types. After defining a <=> operator, the compiler automatically generates all six comparison operators (<, <=, >, >=, ==, !=).
Basic Usage
Comparing primitive types:
| |
Comparing custom types:
| |
Custom comparison logic:
| |
[!note] When you define a custom
operator<=>, you need to explicitly define theoperator==operator, becauseoperator<=>does not automatically generateoperator==. This is primarily for performance considerations:<=>may perform unnecessary ordering comparisons, while==only needs to check for equality.Official explanation:
Once a type has
<=>,==is generated from<=>. For strings,==is typically optimized by first comparing sizes: if the number of characters differs, the strings are not equal. An==generated from<=>would have to read enough of the strings to determine their lexicographical order, which would be much more expensive. After extensive discussion, we decided not to generate==from<=>. - From “Thriving in a Crowded and Changing World”
Summary
Code Simplification: After defining a
<=>operator, the compiler automatically generates all six comparison operators (<,<=,>,>=,==,!=)Performance Optimization: A single comparison yields the complete ordering relationship, avoiding multiple comparisons
Default Implementation: Using
= defaultallows the compiler to automatically generate member-wise lexicographical comparison
https://www.stroustrup.com/hopl20main-p5-p-bfc9cd4--final.pdf
