I'm rearranging the namespaces of code in relatively large C++ project. One difficulty I keep running into is that global operator overloads become inaccessible sometimes. Things like stream operators (<< and >>) and equality operators (==), Sometimes the only changes that cause this is moving from say "namespaceA" to "parent::namespaceA". Namespace "parent" already exists.
I can fix these by explicitly adding:
using ::operator<<;
using ::operator>>;
using ::operator==;
in the affected files (from "namespaceA"), although I was somewhat surprised to see this work.
But this feels like I'm just masking a deeper problem somewhere.
So my question is this: What situations would you expect the masking/hiding o开发者_Go百科f global operators to occur?
Note: I suspected it might be the nested namespaces prevent Koenig Lookup doing its thing, but making some test cases showed this wasn't the issues. Another potentially salient point is that the overloaded global operators affected seem to all be templated functions. However, I'm interested in better understanding how the global namespace operators somehow disappear... all answers appreciated.
Clearly it's something to do with the parent namespace, but I'm not entirely sure what I'm looking for. I can understand an operator being overloaded again so that the wrong version is called, but I'm getting compile errors that can't even find the operators with the right signature!
You're probably forgetting how name lookup works. When you're using operator<<
, it's almost always as a << b
, not ::parent::namespaceA::operator<<(a,b)
. That unqualified use means that it's looked up via Argument Dependent Lookup (aka Koenig Lookup).
So, operators from the global namespace will be hidden by operators from the argument's namespaces.
If there are operators in the namespace they will be found, and the lookup stops there.
Whether it is the "right" overloads or not doesn't matter.
精彩评论