C++ Koenig查找的奇怪行为

C++ Koenig查找的奇怪行为,c++,templates,g++,argument-dependent-lookup,C++,Templates,G++,Argument Dependent Lookup,考虑以下计划: namespace NS2 { class base { }; template<typename T> int size(T& t) { std::cout << "size NS2 called!" << std::endl; return sizeof(t); } }; namespace NS1 { clas

考虑以下计划:

    namespace NS2 {
      class base { };

      template<typename T>
      int size(T& t) {
        std::cout << "size NS2 called!" << std::endl;
        return sizeof(t);
      } 
    };

    namespace NS1 {
      class X : NS2::base { };
    }

    namespace NS3 {
      template<typename T>
      int size(T& t) {
        std::cout << "size NS3 called!" << std::endl;
        return sizeof(t) + 1;
      }

      template<typename T>
      class tmpl 
      {
      public:
        void operator()() { size(*this); }
      };
    };

int main() +{
  NS3::tmpl<NS1::X> t;
  t();
  return 0;
}
名称空间NS2{
类基{};
模板
整数大小(T&T){

std::cout模板参数和基类都会影响ADL,因此我认为GCC是正确的,这里:NS3来自当前范围,NS1来自X模板参数,NS2来自模板参数的基类

您必须以某种方式消除歧义;如果可行,我建议重命名一个或多个函数,或者使用SFINAE消除这些函数的歧义


(类似的情况:请注意boost::noncopyable实际上是“typedef noncopyable_uzation::noncopyable noncopyable;”,因此boost命名空间不会添加到派生自它的ADL类型集中。)

对于那些想要引用的人,请参阅3.4.2/2中的最后一项。