c++ - 什么是 "Argument-Dependent Lookup"(又名 ADL,或 "Koenig Lookup")?

标签 c++ argument-dependent-lookup name-lookup c++-faq

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

最好我想知道:

  • 为什么这是一件好事?
  • 为什么这是一件坏事?
  • 它是如何工作的?

最佳答案

Koenig 查找,或 Argument Dependent Lookup ,描述了编译器如何在 C++ 中查找非限定名称。

C++11 标准 § 3.4.2/1 指出:

When the postfix-expression in a function call (5.2.2) is an unqualified-id, other namespaces not considered during the usual unqualified lookup (3.4.1) may be searched, and in those namespaces, namespace-scope friend function declarations (11.3) not otherwise visible may be found. These modifications to the search depend on the types of the arguments (and for template template arguments, the namespace of the template argument).

简单来说,Nicolai Josuttis 说1:

You don’t have to qualify the namespace for functions if one or more argument types are defined in the namespace of the function.

一个简单的代码示例:

namespace MyNamespace
{
    class MyClass {};
    void doSomething(MyClass) {}
}

MyNamespace::MyClass obj; // global object


int main()
{
    doSomething(obj); // Works Fine - MyNamespace::doSomething() is called.
}

在上面的例子中,既没有using声明也没有using指令,但编译器仍然正确识别了非限定名称doSomething() 作为在命名空间 MyNamespace 中通过应用 Koenig 查找 声明的函数。

它是如何工作的?

该算法告诉编译器不仅要查看本地范围,还要查看包含参数类型的命名空间。因此,在上面的代码中,编译器发现对象 obj,即函数 doSomething() 的参数,属于命名空间 MyNamespace。因此,它查看该命名空间以找到 doSomething() 的声明。

Koenig lookup有什么优势?

如上面的简单代码示例所示,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 lookup”?

因为它是由前 AT&T 和贝尔实验室研究员和程序员设计的, Andrew Koenig .

进一步阅读:


<子> **1** Koenig 查找的定义如 Josuttis 的书*The C++ Standard Library: A Tutorial and Reference* 中所定义。

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

相关文章:

c++ - 在什么情况下参数依赖名称查找(ADL)开始?

c++ - 在c++中为这个对象分配内存

c++ - 模板化函数名称查找难题(ADL)

c++ - 使用引用作为依赖的类成员

c++ - 为什么(不相关的)using 声明可以通过参数依赖查找调和重载歧义?

c++ - 名称查找问题,GCC 和 clang 不同意

c++ - 名称查找和运算符重载如何工作?

c++ - 无法调用命名空间方法

c++ - 在命令行参数中使用引号

c++ - 修改boost多索引容器项