Since I need to add an operator& for the std::tr1::array<bool, N> I wrote the following lines
template<std::size_t N>
std::tr1::array<bool, N>
operator& (const std::tr1::array<bool, N>& a,
const std::tr1::array<bool, N>& b)
{
std::tr1::array<bool, N> result;
std::transform(a.begin(), a.end(), b.begin(), result.begin(),
std::logical_and<bool>());
return result;
}
Now I don’t know in which namespace I’ve to put this function. I considered the std namespace as a restricted area. Only total specialization and overloaded function templates are allowed to be added by the user. Putting it into the global namespace isn’t “allowed” either in order to prevent pollution of the global namespace and clashes with other declarations. And finally putting this function into the namespace of the project doesn’t work since the compiler won’t find it there.
What had I best do? I don’t want to write a new array class putted into the project namespace. Because in this case the compiler would find the right namespace via argument dependent name lookup. Or is this the only possible way because writing a new operator for existing classes means extending their interfaces and this isn’t allowed either for standard classes?
I fully support GMan and sbk who told you to use a named function instead of an operator. Contrary to popular believe, overloading operators is always almost wrong, because it almost never adds clarity to the code. There are surprisingly few exceptions. Among them are the stream input and output operators as well as the arithmetical operators should you implement a number-like type. (And just how likely is that outside of a book teaching you operator overloading?) Note that some people frown upon the std lib overloading
+(and+=, of course) forstd::stringfor the same reason (and others, like thata+b==b+aholds for numbers, but not for strings) – and IMO they do have a point.Anyway if one wanted to do this despite all advice:
When you try to invoke the operator, the compiler tries to find it in the namespace it was invoked in, all enclosing namespaces, and the namespaces of all the arguments. (The latter is called argument-dependent lookup or Koenig lookup.) The namespace of the argument is
std, which you must not add an overload to. So that leaves the namespace the operator is invoked in and its enclosing namespaces – including the global namespace, which encloses all others – to put the operator in.So if you want to implement it despite all warnings, put it in the namespace where it is used in. If it is used in several namespaces, put it into the one that encloses all these. If that’s the global namespace, so be it.
Oh, and did I mention you should not implement this as an overloaded operator?