I have a small piece of code here for your consideration which puzzles me quite a lot. The strange thing is that it compiles on both Sun Studio and GCC even though I think it should not.
Consider this:
namespace name { class C { int a; }; void f(C c); void g(int a); } int main(int argc, char** argv) { name::C c; name::f(c); f(c); // <--- this compiles, strangely enough name::g(42); // g(42); <--- this does not, as I expected }
The class argument from the same namespace causes the function f
to 'leak' out of the namespace and be accessible without name::
.
Does anybody have an explanation for this? It is certainly me and not the compiler being wrong here.
It's called argument-dependent lookup (or Koenig lookup). In short, the compiler will look for the function in namespaces that are the namespaces of argument types.
This is Argument-Dependent Name Lookup, a.k.a. ADL, a.k.a. Koenig lookup. This was invented to make operators work as expected, e.g.:
namespace fu { struct bar { int i; }; inline std::ostream& operator<<( std::ostream& o, const bar& b ) { return o << "fu::bar " << b.i; } } fu::bar b; b.i = 42; std::cout << b << std::endl; // works via ADL magic
Without ADL you'd have to either explicitly bring the output operator with ugly using fu::operator<<;
, or use even uglier explicit call:
fu::operator<<( std::cout, b ) << std::endl;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With