cigien
cigien

Reputation: 60218

Why is operator!= synthesized from operator==, but not the other way around?

In c++20, if I provide an operator== for a type, then the compiler synthesizes an operator!=, but not the other way around.

Here's some code:

struct A {};
bool operator==(A const&, A const&); 

struct B {};
bool operator!=(B const&, B const&); 

int main()
{
    if (A{} != A{}) {}  // error in c++17 
                        // ok in c++20

    if (B{} == B{}) {}  // error in c++17 
                        // error in c++20, why?
}

This seems inconsistent, since != and == are required to be contrary, and if one can be synthesized from the other, then the inverse should work too. What is the reason for this?

Upvotes: 7

Views: 753

Answers (1)

Barry
Barry

Reputation: 302787

Because this adds complexity to the language for no benefit.

The primary operation is equality. C++20 lets you just define operator== to get the full complement of equality operations (== and !=). Likewise, the primary ordering operation is <=> and C++20 lets you just define that and get the full complement of ordering operators (<, <=, >, and >=).

There's no reason to add arbitrary extra flexibility here. Why would you just implement operator!= when you could just implement operator==?


The language currently has a nice symmetry between == and <=> that I think is valuable and important, from the perspective of understanding the rules and building functionality. While you could define x == y as not (x != y) - that seems inherently strange to me since the name of the "not equals" is... not "equals", but you could do that. But you definitely wouldn't want to define x <=> y in terms of x < y or x <= y. That would be an expensive transformation that couldn't even determine the comparison category properly. So such a direction would break the symmetry with ordering that we have, making the language rules harder to understand.

Upvotes: 11

Related Questions