为了账号安全,请及时绑定邮箱和手机立即绑定

什么是“依赖于参数的查找”(又名ADL,还是“Koenig Lookup”)?

什么是“依赖于参数的查找”(又名ADL,还是“Koenig Lookup”)?

C++ C
叮当猫咪 2019-06-03 16:28:05
什么是“依赖于参数的查找”(又名ADL,还是“Koenig Lookup”)?关于什么是依赖于查找的论点,有什么好的解释?许多人也称它为Koenig Lookup。最好我想知道:为什么这是件好事?为什么这是件坏事?它怎麽工作?
查看完整描述

4 回答

?
胡子哥哥

TA贡献1825条经验 获得超6个赞

在Koenig查找中,如果调用一个函数而不指定其命名空间,则函数的名称为在定义参数类型的命名空间中搜索。这就是为什么它也被称为参数相关名称查找简单地说ADL.

正是由于Koenig查找,我们可以这样写:

std::cout << "Hello World!" << "\n";

否则,我们将不得不写:

std::operator<<(std::operator<<(std::cout, "Hello World!"), "\n");

这真的是太多的输入和代码看起来真的很难看!

换句话说,在没有Koenig查找的情况下,甚至你好世界程序看起来很复杂。


查看完整回答
反对 回复 2019-06-03
?
潇湘沐

TA贡献1816条经验 获得超6个赞

也许最好从为什么开始,然后再去如何。

当引入名称空间时,想法是在名称空间中定义所有内容,这样单独的库就不会相互干扰。然而,这给运营商带来了一个问题。例如,查看以下代码:

namespace N{
  class X {};
  void f(X);
  X& operator++(X&);}int main(){
  // define an object of type X
  N::X x;

  // apply f to it
  N::f(x);

  // apply operator++ to it
  ???}

你当然可以写N::operator++(x),但这会使操作者超载的整个问题化为乌有。因此,必须找到允许编译器找到的解决方案。operator++(X&)尽管它不在范围之内。另一方面,它仍然找不到另一个operator++定义在另一个不相关的名称空间中,这可能会使调用变得模糊(在这个简单的示例中,不会出现歧义,但在更复杂的示例中,可能会出现歧义)。解决方案是参数依赖查找(ADL),因为查找依赖于参数(更确切地说,取决于参数的类型)。由于该方案是由AndrewR.Koenig发明的,因此也常被称为Koenig查找。

诀窍是,对于函数调用,除了普通的名称查找(在使用点上查找作用域中的名称)之外,在给定给函数的参数类型的范围内进行第二次查找。因此,在上面的示例中,如果您编写x++总的来说,它是在寻找operator++不仅在全局范围内,而且在xN::X的定义,即namespace N..在那里它找到了一个匹配的operator++,因此x++只是起作用了。另一个operator++在另一个名称空间中定义,例如N2却找不到。由于ADL不限于命名空间,所以您也可以使用f(x)而不是N::f(x)在……里面main().


查看完整回答
反对 回复 2019-06-03
?
回首忆惘然

TA贡献1847条经验 获得超11个赞

在我看来,并不是所有的事情都是好的。人们,包括编译器供应商,一直在侮辱它,因为它有时是不幸的行为。

ADL负责对C+11中的量程回路进行大修.要理解为什么ADL有时会产生意想不到的效果,请考虑不仅要考虑定义参数的命名空间,还要考虑参数的模板参数、函数类型的参数类型/指针类型的参数类型、这些参数的指针类型等等。

一个使用Boost的例子

std::vector<boost::shared_ptr<int>> v;auto x = begin(v);

如果用户使用了.range库,这会导致歧义,因为这两个库都是std::begin被找到(由ADL使用std::vector)和boost::begin被找到(由ADL使用boost::shared_ptr).


查看完整回答
反对 回复 2019-06-03
  • 4 回答
  • 0 关注
  • 988 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信