Pregunta

Ive been reading the Josuttis template book, and Ive been trying to put my head around ADL. He says "ADL proceeds by looking up the name in namespaces and classes "assocaited with" the types of the call arguments". Im just trying to see how it works looking up the name in a class. I put an example of my test below. I see how it looks up the name in a namespace.

class bryan_ns {
  public:
  class bryan {
    public:
      enum E { e1 };
      static void bryan_test() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
  };

  void f(bryan::E) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};

void f(int)
{
  std::cout << "::f(int) called\n";
}


int main()
{
  f(bryan_ns::bryan::e1); // calls ::f(int)
}

But if I change bryan_ns to a namespace like so:

namespace bryan_ns {
  public:
  class bryan {
    public:
      enum E { e1 };
      static void bryan_test() { std::cout << __PRETTY_FUNCTION__ << std::endl; }
  };

  void f(bryan::E) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
};

void f(int)
{
  std::cout << "::f(int) called\n";
}


int main()
{
  f(bryan_ns::bryan::e1); // calls bryan_ns::f(bryan::E)
}
¿Fue útil?

Solución

ADL will look in the enclosing namespace of the type, and also inside the type itself. The best example is a friend function that is defined inside the type:

namespace X {
class test {
   friend void f( test ) { std::cout << "test" << std::endl; }
};
}
int main() {
   X::test t;
   f( t );
}

The call to f(t) will find X::f whose declaration is only available inside the type test. This is a little known feature of friend function declarations: they declare a namespace level function, but provide the declaration only inside the type. A simple test to verify this behavior:

namespace X {
   class test {
      friend void f( test );
   };
   //void f( test );          // [1]
}
void X::f( X::test ) {}       // [2]
int main() {
   X::test t;
   f(t);                      // [3]
}

The definition in [2] will trigger a compilation error, as you can only define a function that has already been declared, and as [2] is outside of the namespace X that definition does not serve the purpose of self-declaration (if you define a function inside the namespace where it resides, then the definition is also a declaration, but not in this case). If we uncomment [1] the error would go away. Alternatively, if we comment [2], the code will compile indicating that for the call in [3], ADL has found the declaration inside the class.

Otros consejos

In the first example, bryan_ns::f is a non-static member function. The expression in main has no . or -> member operator, so it is obviously not a member function call and bryan_ns::f is not a viable function.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top