什么是“参数相关查找"?(又名 ADL,或“Koenig Lookup")? [英] What is "Argument-Dependent Lookup" (aka ADL, or "Koenig Lookup")?

查看:32
本文介绍了什么是“参数相关查找"?(又名 ADL,或“Koenig Lookup")?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于什么是参数依赖查找有什么好的解释?许多人也称它为 Koenig Lookup.

What are some good explanations on what argument dependent lookup is? Many people also call it Koenig Lookup as well.

最好我想知道:

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

推荐答案

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

Koenig Lookup, or Argument Dependent Lookup, describes how unqualified names are looked up by the compiler in C++.

C++11 标准 § 3.4.2/1 规定:

The C++11 standard § 3.4.2/1 states:

当函数调用 (5.2.2) 中的 postfix-expression 是 unqualified-id 时,可能会搜索在通常的非限定查找 (3.4.1) 期间未考虑的其他名称空间,并且在这些名称空间中,名称空间范围的朋友可能会发现不可见的函数声明 (11.3).这些对搜索的修改取决于参数的类型(对于模板模板参数,模板的命名空间论据).

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:

In simpler terms Nicolai Josuttis states1:

如果在函数的命名空间中定义了一种或多种参数类型,则不必限定函数的命名空间.

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 查找 声明的函数.

In the above example there is neither a using-declaration nor a using-directive but still the compiler correctly identifies the unqualified name doSomething() as the function declared in namespace MyNamespace by applying Koenig lookup.

该算法告诉编译器不仅要查看本地作用域,还要查看包含参数类型的命名空间.因此,在上面的代码中,编译器发现作为函数doSomething()的参数的对象obj属于命名空间MyNamespace.因此,它会查看该命名空间以定位 doSomething() 的声明.

The algorithm tells the compiler to not just look at local scope, but also the namespaces that contain the argument's type. Thus, in the above code, the compiler finds that the object obj, which is the argument of the function doSomething(), belongs to the namespace MyNamespace. So, it looks at that namespace to locate the declaration of doSomething().

如上面的简单代码示例所示,Koenig 查找为程序员提供了便利和易用性.如果没有 Koenig 查找,程序员会产生开销,需要重复指定完全限定的名称,或者使用大量 using 声明.

As the simple code example above demonstrates, Koenig lookup provides convenience and ease of usage to the programmer. Without Koenig lookup there would be an overhead on the programmer, to repeatedly specify the fully qualified names, or instead, use numerous using-declarations.

过度依赖 Koenig 查找会导致语义问题,有时会让程序员措手不及.

Over-reliance on Koenig lookup can lead to semantic problems, and catch the programmer off guard sometimes.

考虑 std::swap 的例子,这是交换两个值的标准库算法.使用 Koenig 查找时,必须谨慎使用此算法,因为:

Consider the example of std::swap, which is a standard library algorithm to swap two values. With the Koenig lookup one would have to be cautious while using this algorithm because:

std::swap(obj1,obj2);

可能不会表现出与以下相同的行为:

may not show the same behavior as:

using std::swap;
swap(obj1, obj2);

使用 ADL,调用哪个版本的 swap 函数将取决于传递给它的参数的命名空间.

With ADL, which version of swap function gets called would depend on the namespace of the arguments passed to it.

如果存在命名空间A,并且如果A::obj1A::obj2A::swap() 存在,那么第二个示例将导致对 A::swap() 的调用,这可能不是用户想要的.

If there exists a namespace A, and if A::obj1, A::obj2, and A::swap() exist, then the second example will result in a call to A::swap(), which might not be what the user wanted.

此外,如果由于某种原因 A::swap(A::MyClass&, A::MyClass&)std::swap(A::MyClass&, A::MyClass&) 被定义,那么第一个例子将调用 std::swap(A::MyClass&, A::MyClass&) 但第二个不会编译,因为 swap(obj1, obj2) 会产生歧义.

Further, if for some reason both A::swap(A::MyClass&, A::MyClass&) and std::swap(A::MyClass&, A::MyClass&) are defined, then the first example will call std::swap(A::MyClass&, A::MyClass&) but the second will not compile because swap(obj1, obj2) would be ambiguous.

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

Because it was devised by former AT&T and Bell Labs researcher and programmer, Andrew Koenig.

标准 C++03/11 [basic.lookup.argdep]:3.4.2 依赖参数的名称查找.

Standard C++03/11 [basic.lookup.argdep]: 3.4.2 Argument-dependent name lookup.

这篇关于什么是“参数相关查找"?(又名 ADL,或“Koenig Lookup")?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆