C++中一个名字查找的小知识

简介: 最近看C++标准中的3.4 name lookup章节,碰巧的是stackoverflow也有人提问,他们对这个问题很疑惑,回答的也并不好。 https://stackoverflow.com/questions/25672745/friend-declarations-is-this-a-bug-in-clang 其中C++标准中$3.4.1章节有一个例子: ``` typedef

最近看C++标准中的3.4 name lookup章节,碰巧的是stackoverflow也有人提问,他们对这个问题很疑惑,回答的也并不好。
https://stackoverflow.com/questions/25672745/friend-declarations-is-this-a-bug-in-clang

其中C++标准中$3.4.1章节有一个例子:

typedef int f;
namespace N {
     struct A {
        friend void f(A &);
        operator int();
        void g(A a) {
            int i = f(a);
            // f is the typedef, not the friend
            // function: equivalent to int(a)
        }
    };
}

标准上的注解的意思是f最终是一个typedef, 不会使用friend void f(A&)这个函数。

我自己的理解是:

  1. 在类中声明的friend函数在普通查找中,是不可见的,除非在类声明之前有正式的声明,也就是说friend声明不能代替正式的声明,这是标准所规定的。既然是不可见的,就不会hide掉那个typedef的f。标准$3.3.10讲的name hiding在这里不起作用。
  2. 名字查找要是从普通查找开始的,普通查找就是从内到外一层层地找,找到一个名字,立马停止。在这里找到了f是typedef。普通查找完成后才有ADL查找。
  3. 因为2找到的是typedef,不是一个函数,所以ADL不会介入。ADL是C++11的新规则。如果函数调用是非限定的,例如不是: 某namespace::f(a), 某class::f(a), object_ptr->f(a), 或者object.f(a)之类的调用,并且参数是用户定义类型,就会发起ADL,它把函数调用中的参数所属的namespace也拉进来找这个函数f。所以ADL介入的条件是要么普通查找找不到这个名字或者找到了而且确实是个函数,那么就把参数所属的namespace也拉进来找,最后凑成一个函数集合,做重载解析规则选出最合适的函数。
    在这个例子中如果把typedef int f改成 int f()就会发生ADL。普通查找首先会找到int f(),因为是函数,所以用ADL继续找,找到void f(A&),编译器会说"error: void value not ignored as it ought to be"。

这是由于ADL能找到只声明为friend而没有正式声明的函数,标准就是这么规定。并且void f(A&)比int f()更合适,但是void赋值给 i肯定出错,所以编译器报错啦。

目录
相关文章
|
算法
查找
查找是指在图中寻找特定的节点或边的过程。在图中进行查找操作可以帮助我们找到与目标节点或边相关的信息,或者判断图中是否存在某个节点或边。 在图中进行查找操作的常见算法有: 1. 深度优先搜索(DFS):从图中的一个节点开始,沿着一条路径一直深入直到无法再深入为止,然后回溯到上一个节点,继续深入其他路径,直到找到目标节点或遍历完所有节点。 2. 广度优先搜索(BFS):从图中的一个节点开始,先访问它的所有邻居节点,然后再依次访问邻居的邻居节点,直到找到目标节点或遍历完所有节点。 3. Dijkstra算法:用于在带权有向图中找到从一个节点到其他节点的最短路径。该算法通过不断更新节点的最短距离来逐步
80 0
|
7月前
查找数据
查找数据。
37 1
|
7月前
|
弹性计算 运维 Shell
|
存储 C语言
【C语言】通讯录(添加、删除、查找、修改、显示、清空、按名字排序)
【C语言】通讯录(添加、删除、查找、修改、显示、清空、按名字排序)
|
tengine 安全 算法
结构体定义的名字只是名字而已,还需要利用名字再定义一次
结构体定义的名字只是名字而已,还需要利用名字再定义一次
|
开发者 Python
查找相关的方法 | 学习笔记
快速学习查找相关的方法
|
编译器 C语言 C++
C++中函数名字前的&或*
C++中函数名字前的&或*
752 0
C++中函数名字前的&或*
|
存储 机器学习/深度学习 算法
如何更快速地查找
查找算法在计算机程序设计中占据着主要的核心位置,查找算法的效率直接影响着计算机程序设计与开发的结果与速度。本章主要会讲到顺序查找、二分查找、索引查找和哈希查找这四种查找算法以及效率分析。掌握了相关查找算法,不管是在代码编程计算机技术上面,还在日常生活中都会有很大的用处。
273 0
如何更快速地查找