关于什么是参数相关查找有什么好的解释?许多人也称它为 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() 正确识别为命名空间 MyNamespace 中声明的函数。
    它是如何工作的?
    该算法告诉编译器不仅要查看局部作用域,还要查看包含参数类型的命名空间。因此,在上面的代码中,编译器发现对象 obj ,它是函数 doSomething() 的参数,属于命名空间 MyNamespace 。因此,它会查看该命名空间以定位 doSomething() 的声明。
    Koenig 查找的优势是什么?
    正如上面的简单代码示例所示,Koenig 查找为程序员提供了便利和易用性。如果没有 Koenig 查找,程序员会产生开销,需要重复指定完全限定名称,或者使用大量 using 声明。
    为什么批评 Koenig 查找?
    过度依赖 Koenig 查找会导致语义问题,有时会让程序员措手不及。
    考虑 std::swap 的示例,它是交换两个值的标准库算法。对于 Koenig 查找,在使用此算法时必须谨慎,因为:
    std::swap(obj1,obj2);
    
    可能不会表现出与以下相同的行为:
    using std::swap;
    swap(obj1, obj2);
    
    使用 ADL,调用哪个版本的 swap 函数将取决于传递给它的参数的命名空间。
    如果存在命名空间 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 和贝尔实验室研究员和程序员 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/51161099/

    10-11 15:30