Does the C++ standard guarantee that (x!=y)
always has the same truth value as !(x==y)
?
I know there are many subtleties inv
Does the C++ standard guarantee that
(x!=y)
always has the same truth value as!(x==y)
?
No it doesn't. Absolutely nothing stops me from writing:
struct Broken {
bool operator==(const Broken& ) const { return true; }
bool operator!=(const Broken& ) const { return true; }
};
Broken x, y;
That is perfectly well-formed code. Semantically, it's broken (as the name might suggest), but there's certainly nothing wrong from it from a pure C++ code functionality perspective.
The standard also clearly indicates this is okay in [over.oper]/7:
The identities among certain predefined operators applied to basic types (for example,
++a ≡ a+=1
) need not hold for operator functions. Some predefined operators, such as+=
, require an operand to be an lvalue when applied to basic types; this is not required by operator functions.
In the same vein, nothing in the C++ standard guarantees that operator<
actually implements a valid Ordering (or that x
, etc.). Some standard library implementations will actually add instrumentation to attempt to debug this for you in the ordered containers, but that is just a quality of implementation issue and not a standards-compliant-based decision.
Library solutions like Boost.Operators exist to at least make this a little easier on the programmer's side:
struct Fixed : equality_comparable {
bool operator==(const Fixed&) const;
// a consistent operator!= is provided for you
};
In C++14, Fixed
is no longer an aggregate with the base class. However, in C++17 it's an aggregate again (by way of P0017).
With the adoption of P1185 for C++20, the library solution has effectively becomes a language solution - you just have to write this:
struct Fixed {
bool operator==(Fixed const&) const;
};
bool ne(Fixed const& x, Fixed const& y) {
return x != y;
}
The body of ne()
becomes a valid expression that evaluates as !x.operator==(y)
-- so you don't have to worry about keeping the two comparison in line nor rely on a library solution to help out.