Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Functions with class arguments are leaked from a namespace?

Tags:

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.

like image 592
lytenyn Avatar asked Feb 03 '11 13:02

lytenyn


2 Answers

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.

like image 50
Tim Martin Avatar answered Oct 13 '22 01:10

Tim Martin


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; 
like image 23
Nikolai Fetissov Avatar answered Oct 12 '22 23:10

Nikolai Fetissov