Basti
Basti

Reputation: 2438

How to use three-way comparison (spaceship op) to implement operator== between different types?

Simple Task: I have these two types

struct type_a{
   int member;
};

struct type_b{
   int member;
};

I want to use this new C++20 spaceship op that everyone says is so cool to be able to write type_a{} == type_b{}. I didn't manage to do that. Even if I write operator<=> between them, I only ever can call type_a{} <=> type_b{}, but never a simple comparison. That confuses me as with a single class, the three-way comparison also defines all the others.

Alternative formulation? How to make it so that std::three_way_comparable_with<type_a, type_b> is true?

Upvotes: 3

Views: 1001

Answers (2)

Barry
Barry

Reputation: 302757

The premise of the question is wrong. You don't use the three-way comparison operator (<=>) to implement ==: you use == to implement ==:

bool operator==(type_a a, type_b b) {
    return a.member == b.member;
}

The source of confusion is that there is one exception to this rule: if a type declares a defaulted <=> then it also declares a defaulted ==:

struct type_c {
    int member;
    auto operator<=>(type_c const&) const = default;
};

That declaration is equivalent to having written:

struct type_c {
    int member;
    bool operator==(type_c const&) const = default;
    auto operator<=>(type_c const&) const = default;
};

But it's not the <=> that gives you ==: it's still the ==, and only ==, that gives you ==.

Upvotes: 6

eerorika
eerorika

Reputation: 238311

I recommend making one type convertible to the other:

struct type_a{
   int member;
   friend auto operator<=>(const type_a&, const type_a&) = default;
};

struct type_b{
   int member;
   operator type_a() {
       return {member};
   }
};

This was the solution before operator<=> too, but now it's simpler to define the comparisons for the common type.

Upvotes: 0

Related Questions