什么是“参数依赖查找” (也称为ADL或“Koenig Lookup”)? [英] What is "Argument-Dependent Lookup" (aka ADL, or "Koenig Lookup")?

查看:343
本文介绍了什么是“参数依赖查找” (也称为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.

我最好知道:

    $ b
  • 为什么是好事?
  • Why is it a good thing?
  • Why is it a bad thing?
  • How does it work?


(注意:这是一个 Stack Overflow的C ++常见问题。)

推荐答案

Koenig Lookup 通常也被称为 参数依赖在C ++中查找 ,大​​多数标准C ++编译器支持它。

Koenig Lookup is also commonly known as Argument Dependent Lookup in C++ and most of the Standard C++ compilers support it.

C ++ 11标准§3.4.2 / 1说明:

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


当函数调用(5.2.2)中的postfix-expression是非限定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-directive ,但仍然编译器正确地标识了非限定名 doSomething()作为通过应用 Koenig算法在命名空间 MyNamespace 中声明的函数。

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 the Koenig algorithm.

它是如何工作的?

该算法告诉编译器不只是看局部作用域,包含参数类型的命名空间。因此,在上面的代码中,编译器发现对象 obj 是函数的参数 doSomething(),属于命名空间 MyNamespace 。因此,它查找该命名空间以定位 doSomething()的声明。

How does it work?
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 Lookup 的优点

由于上面的简单代码示例演示了上述Koenig算法提供了方便和易于使用的程序员。没有Koenig算法,会对程序员产生开销,重复指定完全限定名称,或者使用大量使用声明。

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

为什么批评 Koenig算法

Over对Koenig算法的依赖可能导致语义问题,并且有时阻止程序员。

Why the criticism of Koenig Algorithm?
Over dependence on Koenig Algorithm 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 algorithm 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 函数被调用将取决于传递给它的参数的命名空间。

如果存在一个命名空间 A A: :obj1 A :: obj2 & A :: swap()存在,那么第二个示例将导致调用 A :: swap()

With ADL, which version of swap function gets called would depend on the namespace of the arguments passed to it.
If there exists an namespace A and if A::obj1, A::obj2 & 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 :: 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.

琐事:

为什么叫 Koenig Lookup

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

Trivia:
Why is it called Koenig Lookup?
Because it was devised by former AT&T and Bell Labs researcher and programmer,Andrew Koenig.

良好阅读:

Herb Sutter的名字查找功能

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


sup> Koenig算法的定义如Josuttis的书 The C ++ Standard Library:A Tutorial and Reference 中所定义。

1 The definition of Koenig Algorithm is as defined in Josuttis's book, The C++ Standard Library: A Tutorial and Reference.

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

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