【问题标题】:Does argument dependent lookup only search namespaces or classes too?依赖于参数的查找是否也只搜索命名空间或类?
【发布时间】:2012-07-13 00:11:00
【问题描述】:

我一直在阅读 Josuttis 模板书,并且一直在尝试了解 ADL。他说“ADL 通过在命名空间和类中查找名称来“与”调用参数的类型“相关联”。我只是想看看它是如何在班级中查找名称的。我在下面放了一个测试示例。我看到它是如何在命名空间中查找名称的。

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

但如果我将 bryan_ns 更改为这样的命名空间:

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

【问题讨论】:

    标签: c++ argument-dependent-lookup


    【解决方案1】:

    ADL 将查看类型的封闭命名空间,以及类型本身的内部。最好的例子是在类型内部定义的友元函数:

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

    对f(t) 的调用将找到X::f,其声明仅在test 类型中可用。这是友元函数声明的一个鲜为人知的特性:它们声明一个命名空间级别的函数,但只在类型内部提供声明。验证此行为的简单测试:

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

    [2]中的定义会触发编译错误,因为你只能define一个已经声明过的函数,而[2]不在命名空间X 该定义不用于自我声明的目的(如果您在它所在的命名空间内定义了一个函数,那么该定义也是一个声明,但在这种情况下不是)。如果我们取消注释 [1],错误就会消失。或者,如果我们注释 [2],代码将编译,表明对于 [3] 中的调用,ADL 已在类中找到声明。

    【讨论】:

    • 非常感谢,非常感谢您的帮助。你帮助我终于明白了这一点。
    【解决方案2】:

    在第一个示例中,bryan_ns::f 是一个非静态成员函数。 main 中的表达式没有. 或-&gt; 成员运算符,因此显然不是成员函数调用,bryan_ns::f 不是可行函数。

    【讨论】:

    • 将其更改为 static 不会修复它:)
    • bryan_ns::f 不是成员函数
    • 原帖中有两个程序。在第一个程序中,f 是一个成员函数。第二,f 不是成员函数。
    猜你喜欢
    • 1970-01-01
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-15
    • 1970-01-01
    • 2021-04-06
    • 1970-01-01
    相关资源
    最近更新 更多