什么是依赖于参数的查找有哪些好的解释?许多人也称其为Koenig Lookup。

最好我想知道:

  • 为什么这是一件好事?
  • 为什么不好?
  • 如何运作?
  • 最佳答案

    Koenig查找 Argument Dependent Lookup ,描述了C++中的编译器如何查找不合格的名称。
    C++ 11标准第3.4.2/1条规定:

    简单来说,尼古拉·乔苏蒂斯(Nicolai Josuttis)说:

    一个简单的代码示例:

    namespace MyNamespace
    {
        class MyClass {};
        void doSomething(MyClass) {}
    }
    
    MyNamespace::MyClass obj; // global object
    
    
    int main()
    {
        doSomething(obj); // Works Fine - MyNamespace::doSomething() is called.
    }
    
    在上面的示例中,既没有using声明,也没有using伪指令,但是编译器仍然可以通过应用Koenig查找,正确地将不合格名称doSomething()标识为在 namespace MyNamespace中声明的函数。
    它是如何工作的?
    该算法告诉编译器不仅要查看局部作用域,还要查看包含参数类型的 namespace 。因此,在上面的代码中,编译器发现对象obj作为函数doSomething()的参数属于命名空间MyNamespace。因此,它将查看该命名空间以查找doSomething()的声明。
    Koenig查找的优点是什么?
    如上面的简单代码示例所示,Koenig查找为程序员提供了便利和易用性。如果没有Koenig查找,那么程序员将不得不负担重复指定完全限定名称的开销,或者使用大量using -declaration。
    为什么批评Koenig查找?
    过度依赖Koenig查找会导致语义问题,有时会使程序员措手不及。
    考虑的示例 std::swap ,它是交换两个值的标准库算法。使用Koenig查找时,使用此算法时必须谨慎,因为:
    std::swap(obj1,obj2);
    
    可能不会显示以下行为:
    using std::swap;
    swap(obj1, obj2);
    
    使用ADL,调用哪个版本的swap函数将取决于传递给它的参数的 namespace 。
    如果存在命名空间A,并且如果存在A::obj1A::obj2A::swap(),则第二个示例将导致对A::swap()的调用,这可能不是用户想要的。
    此外,如果出于某种原因同时定义了A::swap(A::MyClass&, A::MyClass&)std::swap(A::MyClass&, A::MyClass&),则第一个示例将调用std::swap(A::MyClass&, A::MyClass&),但第二个示例将无法编译,因为swap(obj1, obj2)可能会模棱两可。
    琐事:
    为什么称为“Koenig查找”?
    因为它是由前AT&T和Bell Labs的研究人员兼程序员设计的,所以 Andrew Koenig
    进一步阅读:
  • Herb Sutter's Name Lookup on GotW
  • 标准C++ 03/11 [basic.lookup.argdep]:3.4.2与参数相关的名称查找。

  • ** 1 ** Koenig查找的定义在Josuttis的书《 The C++ Standard Library:A Tutorial and Reference》中定义。

    关于c++ - 什么是 “Argument-Dependent Lookup”(又名ADL或 “Koenig Lookup”)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8111677/

    10-11 22:23