It is unclear why you want the operators to live in a different namespace than your types. In general the recommendation is that operators should live in the same namespace as the user defined types on which they operate. Doing so enables Argument Dependent Lookup, which in turn will help finding the correct operator when you use it (and will solve your compilation error).
If there is a real reason to have the operators in a different namespace, you can provide a tag type in that namespace and then use inheritance to force ADL to look into the nested namespace (the using-directive won't help with ADL):
namespace A {
namespace operators {
struct tag {};
}
struct B : operators::tag {};
namespace operators {
std::ostream& operator<<(std::ostream& out, const ::A::B& obj) { ... }
}
}
namespace C {
void foo() {
::A::B b;
std::cout << b;
}
}
Note that this is somehow of a hack, and some people will be surprised that the operators are not defined in the A
namespace... it works because the set of associated namespaces for a type includes the namespace where the type is defined and also the namespaces of all of it's bases (in this case, ::A::operators
is pulled due to the inheritance relationship between ::A::B
and ::A::operators::tag
)
NOTE: If you define the operators in the same namespace as the type, then you don't need the using-directive at all, as ADL will find them when needed.