User-defined operator<=> and user-defined operator==

Back
-2
votes
0 answers

Consider the following program (demo):

#include <compare>

struct X {
    std::strong_ordering operator<=>(const X&) const;

    bool operator==(const X& rightOp) const {
        return (*this <=> rightOp) == 0;
    }
};

X x1, x2;
bool equal = x1 == x2;
bool less  = x1 < x2;

This program compiles, but to my surprise, if I remove operator==, x == x no longer compiles (although x < x continues to compile). Thus, a user-defined operator<=> generates <, >, <=, >=, but not ==, !=. (Also surprisingly, a defaulted one generates all 6 operators.)

If I write a operator<=> myself, why am I forced to write a boilerplate operator== too? With operator<=> I consider all 6 operators covered.

My reasoning

There are indeed classes for which we can imagine multiple types of comparison. Strings are a good example. They can be compared in a case-sensitive or case-insensitive manner, with or without considering diacritics, and so on. However, I would argue that all operators (==, !=, <, >, <=, >=) should represent a single comparison type. Any other comparison type should be provided through explicitly named functions, such as IsEqualCaseInsensitive() or IsLessCaseInsensitive().

C++ appears to allow == and != to belong to one comparison type, while <, >, <=, >= belong to another. I think this only creates confusion. Is there a good reason for separating the two?

User Dr. Gut
7/11/2026, 2:27:21 AM
View on Stack Overflow

Answers (0)

No answers available for this question on Stack Overflow.