无限定名称查找

(关键字:懒惰,挑捡,using指令的特殊性)

  • 无限定名称查找实际上就是指没有限定(名称空间和名称空间运算符)名存在的一个名字的出现,其中对于using指令,其内部包含的所有的声明是被当成在当前包含它的最内存块的使用该指令的位置上按照顺序声明的
  • 无限定名称查找规则如下:
    • 大部分情况下,都将全部搜索当前名字使用点之前的所有部分,顺序为当前块(含嵌套),当前名称空间,直至全局,一但找到相应的名字就停止查找.例子:
    namespace N{
    extern int x;
    int i = 4;
    namespace NN{
    int i = 5;
    void f();
    }
    }
    int i = 2;
    int N::x = i; //此时按照名称查找顺序则有限找到使用点之前的,名称空间内的i.
    void N::NN::f(){
    int i = 6;
    {
    int j = i;//此时的i先从块作用域向上找,到函数块,再到函数的名称空间,逐层往外.
    }
    }
    • 但是对于类,及其成员函数定义内出现的名字,则有一定其他规则:

      • 对于类内的在非成员函数内出现的名字(包括其嵌套类),查找顺序在以上的查找规则下,增加了:当在当前类使用点之前找不到之后,优先找基类,之后外围块(找到就停止)

        • 如果外围的块是一个类那么,也优先到其基类(但是基类的递归过程不包括基类的名称空间)
        • 如果是块(名称空间),那么就是包括其的名称空间,依此递归,直到全局
      • 对于成员函数定义内出现的名字查找规则则是分别对当前类可直接查找到的目标的名字纳入一个当前集合,找不到时对其基类同样创建一个所有可以查找到的目标的名字的集合,并且有以下基本原则:
        • 对于using声明,则表示当前using的名字直接纳入当前查找集合内
        • 单继承模型: 如果当前类C的查找集合为空,基类B(唯一的基类)查找到的话,那么类C的集合就可以直接当作B的集合(实际上是两集合去并集),并且以此递归,直到找到一个时(均为单继承)就结束(即之后基类的集合都将被丢弃,该规则归结为,),例如:
        struct B{
        void foo(){}
        };
        struct C:public B{
        void f(){
        foo(); //此时C的查找集合为空,基类B的查找集合为foo,那么C的查找集合就是C与B的并集,即B的集合内的结果
        }
        };
        • 多继承模型:存在类C有Bi(i = 1 ... n)个基类,依然会对每个类包括基类(以此递归),归纳一个查找集合,对于一个派生类的集合都在基类进行以下处理后并集操作再得出:

          • 若集合合并中,存在一个元素是合并集合中至少两个集合的共同基类,那么丢弃存在该元素的那个集合(注意,共同基类只有同时为那些类的虚基类才可能)

            • 若C中的每个元素均为至少一个基类Bi的基类的元素,那么丢弃集合C
            • 若基类Bi中元素为C中(其他的基类B同C并集产生的)的基类的元素,那么丢弃Bi(即Bi和其他基类共拥一个基类)
          • 合并若出现冲突,则再检查是存在集合为无效(类型等不符合),将无效的(无效即值当前集合发生歧义).
          • 若无法消除,即存在两个都有效的集合,则发生歧义.例子:
          struct A{
          void f();
          };
          struct B1:A{
          void f();
          };
          struct B2:virtual A{};
          struct C:B1,B2{
          void foo(){
          f();
          //错误,在集合C中无元素,B1中有元素B1::f,此时C的元素就是B1的,B2中无元素
          //但是其基类中有A::f故B2元素为A::f,此时C合并B2时,出现歧义.
          }
          };
          struct A{
          void f();
          };
          struct B1:virtual A{
          void f();
          };
          struct B2:virtual A{
          void f(int);
          };
          struct C:B1,B2{
          void foo(){
          f(); //错误,在集合C中无元素,B1中有元素B1::f
          //此时C的元素就是B1的,B2中存在元素B2::f,此时合并时存在歧义.
          }
          };
          struct A{
          void f();
          };
          struct B1:virtual A{};
          struct B2:virtual A{
          // void f(); 当该声明存在时,集合C中的元素为A::f(已经和B1合并)
          //然后由于C中所有元素均为其基类的共同基类(A)的元素所以丢弃C中的声明,合并集合为B2::f
          //当为B1::f时,则由于有基类的元素是C中以加入元素的类(B1)的基类(A)的元素
          //所以B2的A::f丢弃)
          };
          struct C:B1,B2{
          void foo(){
          f();
          //正确,此时B1->C,C的元素为(A::f)
          //当C和B2合并时,由于C中元素均为基类的基类的元素,所以丢弃C的元素,留下B2的
          //或另一条款B2中的元素是已经加入到C的基类的基类的元素则丢弃B2
          }
          };
          struct A{
          void f();
          };
          struct B1: A{};
          struct B2: A{};
          struct C:B1,B2{};
          struct D:A{};
          struct E:C,D{
          void foo(){
          void f(); //集合C无效丢弃,保留E的.
          }
          };
    • 对于友元函数的定义,若在类内定义,则遵循类成员函数的定义的相关规则,在类外定义,则遵循普通函数的相关规则
    • 对于在其他类的函数进行的友元函数的声明,若该函数不是模板,则在该函数中出现的名字有限从该函数的所有类开始查找,若没有再到当前友元声明的类中,若是模板,则只从当前类开始查找,遵循类内声明查找
    • 对于默认形参,在对外围块等查找之前,优先查找前面的形参名字.
    • 对于静态数据成员,查找规则同成员函数定义一致
    • 对于枚举项的声明,出现的名字在查找外围块等前,会查找同一枚举声明中的名字
    • 函数try的catch中的名字,会当作在函数体最开始使用的名字来进行,即当前函数内,只有形参处可以被找到,或函数块外,之后的不可以.
    • 对于重载运算符和模板,则会在重载解析和ADL之后链接补充.

C++ 无限定名称查找的更多相关文章

  1. C++ 限定名称查找

    限定名称查找规则实际归纳下来很简单,先对::左边的名称进行查找(遵循,限定,无限定),然后在左边查找到的(此时只查找类型名称)名字的作用域内(含内联名称空间件)查找右边出现的名字,查找到即存在(故可以 ...

  2. [转] WinForm自定义函数FindControl实现按名称查找控件

    原文地址 WinForm自定义函数FindControl实现按名称查找控件 本文所述实例实现WinForm自定义函数FindControl实现按名称查找控件的功能,在C#程序开发中有一定的实用价值. ...

  3. linux文件名称查找which,whereis,locate

    1. 文件名称查找 使用find查询时.因为磁盘查询.所以速度较慢. 所以linux下查询更常使用which, whereis, locate来查询,因为是利用数据库查询.所以速度非常快. 2. wh ...

  4. SAP MM 供应商无英文名称,ME21N里却带出了英文名字?

    SAP MM 供应商无英文名称,ME21N里却带出了英文名字? 近日收到客户业务用户上报的一个问题说ME21N的时候,供应商101071的名字怎么是英文名字,实际上供应商主数据里是没有这个英文名字, ...

  5. 枚举 switch case 标签必须为枚举常量的非限定名称

    枚举 switch case 标签必须为枚举常量的非限定名称 错误描述: Error:(63, 24) 错误: 枚举 switch case 标签必须为枚举常量的非限定名称. 解决思路: switch ...

  6. c++11-17 模板核心知识(十三)—— 名称查找与ADL

    名称分类 名称查找 ordinary lookup ADL (Argument-Dependent Lookup) 官网的例子 ADL的缺点 在C++中,如果编译器遇到一个名称,它会寻找这个名称代表什 ...

  7. WPF 通过名称查找属性(DependencyProperty)

    使用名称来查找DependencyProperty. 如果有这样的需求,则是需要通过DependencyPropertyDescriptor来查找. 通常是使用附加属性或者依赖属性的方法. 下面给出附 ...

  8. WPF 按名称查找控件

    1FrameworkElement类FindName方法 使用过程 1.容器控件.RegisterName("Name",要注册的控件)   //注册控件 2.容器控件.FindN ...

  9. Qt 按名称查找子节点

    TreeItem* TreeModel::GetItem(QStringList& list, TreeItem* parent ,int deep) { ).toString()) { if ...

随机推荐

  1. $each 遍历json字符串

    $.each遍历json对象   查看一个简单的jQuery的例子来遍历一个JavaScript数组对象. var json = [ {"id":"1",&qu ...

  2. :input获得焦点时被弹出键盘挡住解决办法

    这个是移动端非常常见的bug了,这里说下综合的解决办法,因为有时候你的办法就是会失效.. 上代码 /*input框调起输入法盖住输入问题*/$('input[type="text" ...

  3. POJ1151 Atlantis 线段树扫描线

    扫描线终于看懂了...咕咕了快三个月$qwq$ 对于所有的横线按纵坐标排序,矩阵靠下的线权值设为$1$,靠上的线权值设为$-1$,然后执行线段树区间加减,每次的贡献就是有效宽度乘上两次计算时的纵坐标之 ...

  4. 有效使用Mock编写java单元测试

    Java单元测试对于开发人员质量保证至关重要,尤其当面对一团乱码的遗留代码时,没有高覆盖率的单元测试做保障,没人敢轻易对代码进行重构.然而单元测试的编写也不是一件容易的事情,除非使用TDD方式,否则编 ...

  5. chapter07

    // 包和引入// 包也可以像内部类那样嵌套// 包路径不是绝对路径// 包声明链x.y.x并不自动 将中间包x和x.y变成可见// 位于文件顶部不带花括号的包声明在整个文件范围内有效// 包对象可以 ...

  6. aspnetcore进程内托管的坑-非常规方法解决Log4Net不写日志的问题

    问题描述:Log4Net,本地测试一切正常,发布后,无法自动创建文件夹和日志文件,无法写入文件. 一.在项目中配置Log4Net 请参考我的上一篇博客 <aspnetcore配置log4net并 ...

  7. ubuntu tomcat https

    1.generate key use java key tool -storepass *** 2.sign certificate sudo keytool -export -alias ### - ...

  8. GCD Guessing Game Gym - 100085G 猜数字 gcd

    http://codeforces.com/gym/100085/attachments 因为那个数字是一个质数,这样的猜的次数是最多的,所以至少是质数次. 但是如果需要猜2.3,那么可以直接猜6,也 ...

  9. ElasticSearch 全文检索— ElasticSearch 安装部署

    ElasticSearch 规划-集群规划 ElasticSearch 规划-集群规划 ElasticSearch 规划-用户规划 ElasticSearch 规划-目录规划 ElasticSearc ...

  10. FTP连接报530 User 用户名 cannot log in home directory inaccessible的解决方法

    在server 2003新建ftp用户并开启IIS的Ftp功能之后,有时在连接这个ftp的时候会出现530 User 用户名 cannot log in home directory inaccess ...