Does argument dependent lookup only search namespaces or classes too?

别等时光非礼了梦想. 提交于 2019-12-21 06:17:04

问题


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)
}

回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/11462474/does-argument-dependent-lookup-only-search-namespaces-or-classes-too

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!