Real world usage example for spaceship operator

<=> allows the lazy way to also be the performant way. You don't change your client code.

Clients may see performance benefits when there was a using std::rel_ops (or boost::ordered etc).

An example

// old and busted
struct Person : boost::totally_ordered<Person>
{
    std::string firstname;
    std::string lastname
    bool operator<(const Person & other) 
    { 
        return std::tie(firstname, lastname)
             < std::tie(other.firstname, other.lastname); 
    }
}

// new hotness
struct Person
{
    std::string firstname;
    std::string lastname;
    auto operator<=>(const Person &) = default;
}

int main()
{
    Person person1 { "John", "Smith" };
    Person person2 { "John", "Smith" };
    std::cout << person2 <= person1 << std::endl;
}

You just compare the way you've always done:

a < b

It's just that under the hood, one of the candidate functions for that expression will also find (a <=> b) < 0 and if that candidate exists and happens to be the best viable candidate, then it is invoked.

You typically don't use <=> directly in "client code", you just use the comparisons that you want directly.

For instance, given:

struct X {
    int i;

    // this can be = default, just writing it out for clarity
    strong_ordering operator<=>(X const& rhs) const { return i <=> rhs.i; }
};

The expression

X{42} < X{57};

will evaluate as X{42} <=> X{57} < 0 (there is no < candidate, so <=> non-reversed is trivially the best candidate). X{42} <=> X{57} evaluates as 42 <=> 57 which is strong_ordering::less. And that < 0 returns true. Hence, the initial expression is true... as expected.

The same operator also directly gives us that X{57} > X{42}, that X{3} >= X{2}, etc.


The advantage of <=> is that you only need to write one operator instead of four, that operator is typically much easier to write than <, you can properly express the differentiation between partial and total orders, and stacking it is typically more performant (e.g. in the cases like string).

Additionally, we don't have to live in this weird world where everyone pretends that operator< is the only relational operator that exists.