Reputation: 60218
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
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