It's a lot like how

`strcmp` works. You implement the one operator, the spaceship operator, which is effectively 3-valued:

`a < b` : `(a <=> b) < 0``a == b` : `(a <=> b) == 0``a > b` : `(a <=> b) > 0`

Then, using that single value, from a single operator call, you can determine (compiler generated):

`a == b` : `(a <=> b) == 0``a != b` : `(a <=> b) != 0``a < b` : `(a <=> b) < 0``a > b` : `(a <=> b) > 0``a <= b` : `(a <=> b) <= 0``a >= b` : `(a <=> b) >= 0`

So effectively you get all 6 comparison operators, but only have to implement one.

Previously they had

`std::rel_ops`. Given two operators

`operator==`, and

`operator<`, it would implement the other 4 for you. The problem with

`std::rel_ops` is it didn't play nicely with

ADT (Argument-Dependent Lookup), so sometimes those operators weren't found. Additionally, it added extra template operators to the global namespace, so all structs would end up getting the extra comparison operators, whether you wanted them or not.

The implementation of

`std::rel_ops` might use the following equivalences:

`a != b` : `!(a == b)``a > b` : `(b < a)``a <= b` : `!(a > b)``a >= b` : `!(a < b)`

Note: The above also only require one operator call.

A naive implementation might call two possibly expensive operators:

`a <= b` : `(a < b) || (a == b)`

You want to avoid that.

Another benefit of the

`<=>` operator, is that it can distinguish between the various relational strengths, and only provide overloads that are appropriate. That's a whole other topic, but here are the orderings:

- strong ordering
- weak ordering
- partial ordering
- strong equality
- weak equality

Edit: In regards to a "point" (2D, 3D, etc.), there may be no natural way to do inequality comparisons. Hence the different orderings above, which may exclude auto generation of some comparison operators. In particular, if the return type of the spaceship operator is of the last 2 types, the compiler knows not to generate inequality comparisons.