Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 390
cigien Avatar asked Aug 25 '20 14:08

cigien


1 Answers

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.

like image 81
Barry Avatar answered Oct 07 '22 12:10

Barry