Classes and class hierarchies
C.168
Define overloaded operators in the namespace of their operands
Reason
Readability. Ability for find operators using ADL. Avoiding inconsistent definition in different namespaces
Example
struct S { };
S operator+(S, S); // OK: in the same namespace as S, and even next to S
S s;
S r = s + s;
Example
namespace N {
struct S { };
S operator+(S, S); // OK: in the same namespace as S, and even next to S
}
N::S s;
S r = s + s; // finds N::operator+() by ADL
Example, bad
struct S { };
S s;
namespace N {
bool operator!(S a) { return true; }
bool not_s = !s;
}
namespace M {
bool operator!(S a) { return false; }
bool not_s = !s;
}
Here, the meaning of !s differs in N and M. This can be most confusing. Remove the definition of namespace M and the confusion is replaced by an opportunity to make the mistake.
Note
If a binary operator is defined for two types that are defined in different namespaces, you cannot follow this rule. For example:
Vec::Vector operator*(const Vec::Vector&, const Mat::Matrix&);
This might be something best avoided.
See also
This is a special case of the rule that helper functions should be defined in the same namespace as their class.
Enforcement
- Flag operator definitions that are not in the namespace of their operands