什么是依赖于参数的查找有哪些好的解释?许多人也称其为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的书《 C++标准库:教程和参考》中定义。

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

    10-13 08:30