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

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

关于什么是依赖于查找的论点,有什么好的解释?许多人也称它为Koenig Lookup。

最好我想知道:

  • 为什么这是件好事?
  • 为什么这是件坏事?
  • 它怎麽工作?


叮当猫咪
浏览 989回答 4
4回答

胡子哥哥

在Koenig查找中,如果调用一个函数而不指定其命名空间,则函数的名称为也在定义参数类型的命名空间中搜索。这就是为什么它也被称为参数相关名称查找简单地说ADL.正是由于Koenig查找,我们可以这样写:std::cout&nbsp;<<&nbsp;"Hello&nbsp;World!"&nbsp;<<&nbsp;"\n";否则,我们将不得不写:std::operator<<(std::operator<<(std::cout,&nbsp;"Hello&nbsp;World!"),&nbsp;"\n");这真的是太多的输入和代码看起来真的很难看!换句话说,在没有Koenig查找的情况下,甚至你好世界程序看起来很复杂。

潇湘沐

也许最好从为什么开始,然后再去如何。当引入名称空间时,想法是在名称空间中定义所有内容,这样单独的库就不会相互干扰。然而,这给运营商带来了一个问题。例如,查看以下代码:namespace&nbsp;N{ &nbsp;&nbsp;class&nbsp;X&nbsp;{}; &nbsp;&nbsp;void&nbsp;f(X); &nbsp;&nbsp;X&&nbsp;operator++(X&);}int&nbsp;main(){ &nbsp;&nbsp;//&nbsp;define&nbsp;an&nbsp;object&nbsp;of&nbsp;type&nbsp;X &nbsp;&nbsp;N::X&nbsp;x; &nbsp;&nbsp;//&nbsp;apply&nbsp;f&nbsp;to&nbsp;it &nbsp;&nbsp;N::f(x); &nbsp;&nbsp;//&nbsp;apply&nbsp;operator++&nbsp;to&nbsp;it &nbsp;&nbsp;???}你当然可以写N::operator++(x),但这会使操作者超载的整个问题化为乌有。因此,必须找到允许编译器找到的解决方案。operator++(X&)尽管它不在范围之内。另一方面,它仍然找不到另一个operator++定义在另一个不相关的名称空间中,这可能会使调用变得模糊(在这个简单的示例中,不会出现歧义,但在更复杂的示例中,可能会出现歧义)。解决方案是参数依赖查找(ADL),因为查找依赖于参数(更确切地说,取决于参数的类型)。由于该方案是由AndrewR.Koenig发明的,因此也常被称为Koenig查找。诀窍是,对于函数调用,除了普通的名称查找(在使用点上查找作用域中的名称)之外,在给定给函数的参数类型的范围内进行第二次查找。因此,在上面的示例中,如果您编写x++总的来说,它是在寻找operator++不仅在全局范围内,而且在x,&nbsp;N::X的定义,即namespace N..在那里它找到了一个匹配的operator++,因此x++只是起作用了。另一个operator++在另一个名称空间中定义,例如N2却找不到。由于ADL不限于命名空间,所以您也可以使用f(x)而不是N::f(x)在……里面main().

回首忆惘然

在我看来,并不是所有的事情都是好的。人们,包括编译器供应商,一直在侮辱它,因为它有时是不幸的行为。ADL负责对C+11中的量程回路进行大修.要理解为什么ADL有时会产生意想不到的效果,请考虑不仅要考虑定义参数的命名空间,还要考虑参数的模板参数、函数类型的参数类型/指针类型的参数类型、这些参数的指针类型等等。一个使用Boost的例子std::vector<boost::shared_ptr<int>>&nbsp;v;auto&nbsp;x&nbsp;=&nbsp;begin(v);如果用户使用了.range库,这会导致歧义,因为这两个库都是std::begin被找到(由ADL使用std::vector)和boost::begin被找到(由ADL使用boost::shared_ptr).
打开App,查看更多内容
随时随地看视频慕课网APP