什么是依赖于参数的查找有哪些好的解释?许多人也称其为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::obj1
,A::obj2
和A::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 。
进一步阅读:
1 Koenig查找的定义在Josuttis的书《 C++标准库:教程和参考》中定义。
关于c++ - 什么是 “Argument-Dependent Lookup”(又名ADL或 “Koenig Lookup”)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47555289/