c++ - Koenig 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 {
      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;
}

我的编译器 (gcc 4.3.3) 没有编译程序,因为对 size 的调用不明确。 namespace NS2 似乎已添加到类 tmpl 中用于大小调用的关联 namespace 集中。即使在阅读了 ISI 标准中关于 Koenig Lookup 的部分之后,我也不确定这种行为是否符合标准。是吗? 有没有人知道一种解决此行为的方法,而无需使用 NS3 前缀限定大小调用?

提前致谢!

最佳答案

模板参数和基类都会影响 ADL,所以我认为 GCC 是正确的,这里:NS3 来自当前作用域,NS1 来自 X 模板参数,NS2 来自模板参数的基类。

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

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

关于c++ - Koenig Lookup 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1422056/

相关文章:

c++ - 编译时可配置回调

c++ - CURL 在/usr/include 中,但仍然不会被 g++ 自动找到

c++ - ANTLR语法链接错误

c++ - “dll_file”可能是 '0' : This does not adhere to the specification for the function 'GetProcAddress'

c++ - 模板类C++中两种不同类型的方法

c++ - 无法使用 Microsoft Visual Studio 2012 列出初始化 vector

c++ - 概括具有不同相似类型的 C++ 代码的方法

c++ - 无法将 LIBEVENT 链接为 C++

c++ - Win Mobile 5.0 无法调试和用户WiFi

c++ - arrayfire/lib64 和 libafcu 在哪里?