什么是“参数相关查找”(又名ADL或“Koenig查找”)

关于什么是参数依赖查找有什么好的解释?许多人也称之为 Koenig Lookup。

关于什么是参数依赖查找有什么好的解释?许多人也称之为 Koenig Lookup。

最好我想知道:

为什么这是一件好事?

为什么这是一件坏事?

它是如何工作的?

260

Koenig LookupArgument Dependent Lookup描述了 C++ 编译器如何查找非限定名称。

C ++ 11 标准 § 3.4.2 / 1 规定:

当函数调用(5.2.2)中的 postfix-expression 是 unquacified-id 时,可能会搜索在通常的非限定查找(3.4.1)期间未考虑的其他命名空间,并且在这些命名空间中,可能会找到以其他方式不可见的命名空间范围友元函数声明(11.3)。

简单地说,Nicolai Josuttis 指出1

如果在函数的命名空间中定义了一个或多个参数类型,则不必限定函数的命名空间。

一个简单的代码示例:

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 lookup将非限定名称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::obj1A::obj2A::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 & amp;T 和贝尔实验室的研究人员和程序员设计的,Andrew Koenig

进一步阅读:

Herb Sutter's Name Lookup on GotW

标准 C++ 03 / 11 [basic.lookup.argdep]:3.4.2 依赖于参数的名称查找。

84

在 Koenig Lookup 中,如果在没有指定其命名空间的情况下调用函数,则函数的名称也是在定义参数类型的命名空间中搜索。这就是为什么它也被称为Argument-Dependent name Lookup,简称为ADL

这是因为 Koenig Lookup,我们可以这样写:

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

否则,我们将不得不写:

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

这真的是太多的打字和代码看起来真的很丑!

换句话说,在没有 Koenig Lookup 的情况下,即使是Hello World程序看起来也很复杂。

33

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

当 namespaces 被引入时,想法是在 namespaces 中定义所有内容,以便单独的库不会相互干扰。然而,这引入了操作符的问题。例如看的代码:

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&),尽管它不在范围内。另一方面,它仍然不应该找到另一个2 Lolookup在另一个不相关的命名空间中定义,这可能会使调用变得模棱两可(在这个简单的例子中

诀窍是,对于函数调用,除了正常的名称查找(在使用点查找范围内的名称)之外,还可以在

21

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

ADL 负责对 C ++ 11 中的 for-range 循环进行大修。要理解为什么 ADL 有时会产生意想不到的影响,请考虑不仅要考虑定义参数的命名空间,还要考虑参数的模板参数的参数,函数类型的参数类型 / 这些参数的指针类型的指针类型的参数,等等。

使用 boost 的示例

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

如果用户使用 boost.range 库,则会导致歧义,因为找到std::begin(由 ADL 使用std::vector)和boost::begin(由 ADL 使用boost::shared_ptr)。

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(89)
在将Flux转换为Mono时卡住了吗
上一篇
仅将区号“84”添加到 Python中缺少区号的电话号码
下一篇

相关推荐

  • lua goto语句:深入理解Lua中的Goto语句

    示例示例Lua的goto语句用于跳转到指定的标签。它的语法为:goto 标签…

    2023-07-01 04:39:53
    0 80 53
  • php中文转拼音:中国美食zhongguomeishi

    PHP中文转拼音是指将中文字符串转换成拼音字符串。 PHP中有一些现成的函数可以实现这一功能,比如pinyin_permalink() 和 pinyin_abbr()等,但是这些函数要求安装PECL扩展,而且拼音转换的结果不够准确,在某些情况下可能会出现乱码。…

    2024-10-10 15:35:42
    0 16 80
  • avlang新人php:如何使用PHP编程来提升avlang新人的开发能力

    示例示例avlang新人php是一个基于PHP语言的轻量级编程语言,它拥有简单易用的语法,可以帮助新手快速学习和使用PHP。下面是一个简单的avlang新人php示例:…

    2023-03-27 13:08:10
    0 44 44
  • nginx配置php项目:如何使用Nginx配置PHP项目

    示例示例确定php-fpm的安装路径,修改nginx.conf文件,在http段下添加如下配置:server {…

    2023-03-06 06:00:56
    0 50 91
  • log4j2远程代码执行漏洞修复:修复 Log4j2 远程代码执行漏洞,确保安全性

    示例示例Log4j2远程代码执行漏洞修复主要是通过限制可以运行的代码来实现的。在log4j2的配置文件中,将``属性设置为false,这样就可以阻止远程攻击者使用log4j2的远程视图功能来远程执行代码了。…

    2023-05-30 11:20:01
    0 72 55
  • 编程猫传说之下:没有传说的熊猫情节 ()(legend syn)

    关于编程猫传说之下的问题,在legend syn中经常遇到,在 python 中使用 pandas 库并使用…

    2022-12-13 06:46:21
    0 96 25
  • Lua脚本学习:LuaRobloxgui脚本

    关于Lua脚本学习的问题,在limited words script roblox中经常遇到,当您坐在汽车座椅上时,我制作了一个 GUI,它会告诉您带有“购买”按钮的汽车的速度和价值。我设法只制作了 GUI,但我找不到编写脚本的方法,因此当您单击“购买”时,它会将玩家购买的汽车传送到经销商的后面。无论如何要做吗?…

    2022-11-23 13:17:01
    0 54 62
  • Lighter:比nHibernate轻的东西

    关于Lighter的问题,在something lighter中经常遇到,我想开发一个C#<->;数据库应用程序。我考虑过使用ORM创建类,以便透明地访问我想连接的任何数据库。…

    2022-12-24 01:45:29
    0 13 72

发表评论

登录 后才能评论

评论列表(83条)