Classes and class hierarchies
C.86
Make `==` symmetric with respect to operand types and `noexcept`
Reason
Asymmetric treatment of operands is surprising and a source of errors where conversions are possible. == is a fundamental operation and programmers should be able to use it without fear of failure.
Example
struct X {
string name;
int number;
};
bool operator==(const X& a, const X& b) noexcept {
return a.name == b.name && a.number == b.number;
}
Example, bad
class B {
string name;
int number;
bool operator==(const B& a) const {
return name == a.name && number == a.number;
}
// ...
};
B's comparison accepts conversions for its second operand, but not its first.
Note
If a class has a failure state, like double's NaN, there is a temptation to make a comparison against the failure state throw. The alternative is to make two failure states compare equal and any valid state compare false against the failure state.
Note
This rule applies to all the usual comparison operators: !=, <, <=, >, and >=.
Enforcement
- Flag an
operator==()for which the argument types differ; same for other comparison operators:!=,<,<=,>, and>=. - Flag member
operator==()s; same for other comparison operators:!=,<,<=,>, and>=.