Rule A14-5-3 (advisory, design, automated)
A non-member generic operator shall only be declared in a namespace that does not contain class (struct) type, enum type or union type declarations.
Rationale
Argument-dependent lookup (ADL) adds additional associated namespaces to the set of scopes searched when lookup is performed for the names of called functions. A generic operator found in one of these additional namespaces would be added to the overload set and choosen by overload resolution. ADL is complicated by several possible use forms for operators (via function calls and via expression, operators can be declared as members and as non-members) and lookup in those cases is different, which is likely to be inconsistent with developer expectation. Generic operator is a non-member operator template that can be called without explicit template arguments and has at least one generic parameter. A template type parameter T is a generic parameter if, in the function declaration, it has the (possibly cv-qualified) form of T, or T & or T &&.
Example
// $Id: A14-5-3.cpp $
#include <cstdint>
template<typename T>
class B
{
public:
bool operator+( long rhs );
void f()
{
*this + 10;
}
};
namespace NS1
{
class A {};
template<typename T>
bool operator+( T, std::int32_t ); // Non-Compliant: a member of namespace
// with other declarations
}
namespace NS2
{
void g();
template<typename T>
bool operator+( T, std::int32_t ); // Compliant: a member of namespace
// with declarations of functions only
}
template class B<NS1::A>; // NS1::operator+ will be used in function B::f()
// instead of B::operator+
See also
MISRA C++ 2008 [7]: M14-5-1: A non-member generic function shall only be declared in a namespace that containes only operator declarations.