关于什么是参数相关查找有什么好的解释?许多人也称它为 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::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 和贝尔实验室研究员和程序员 Andrew Koenig 设计的。
进一步阅读:
**1** Koenig 查找的定义在 Josuttis 的书中定义,*C++ 标准库:教程和引用*。
关于c++ - 什么是 "Argument-Dependent Lookup"(又名 ADL,或 "Koenig Lookup")?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55732031/