Good practice: when defining for a class one of the operators <, <=, >, >=, ==, != you should define them all.
Old style code: to add ordering to a class you have to add for each of the operators <, <=, >, >=, ==, != a specific member function
struct SomeClass
{
int val;
bool operator < (const SomeClass& rhs) const {return val < rhs.val;}
bool operator <= ...
...
};
With C++20 and the three way comparison operator (spaceship operator) you get all six operators for free:
#include <compare>
struct SomeClass
{
int val;
auto operator<=> (const SomeClass& rhs) const = default;
};
- The compiler generated three-way comparison operator checks all base classes from left to right and all non static members in their declaration order (lexicographical comparison)
- If you need special handling e.g. because of pointer members you can provide a user defined implementation of operator<=>. In this case you also have to define operator== (the compiler will not automatically rewrite == and != with a custom operator<=> overload)
- Additionally you can define both “
operator<=>
” and e.g. user defined specific “operator<
” within the same class. The compiler will automatically use the specific operator definition where appropriate. User defined operators have a higher priority.
Return value of spaceship operator
auto result = a <=> b;
// result < 0 : a < b
// result == 0 : a == b
// result > 0 : a > b
The compiler automatically converts an expression a < b to the expression (a<=>b) < 0. If there is no type conversion from a to b the compiler uses the expression 0 < (b<=>a).