名字查找

每当一个变量或者一个对象出现,编译器都会进行名字查找(name lookup),以确认这个变量或对象的具体属性。一般情况下,程序会从变量出现的地方开始向上查找,由内向外查找各级作用域直到全局作用域,找到同名的变量声明即停止,若最终没找到则报错。

#include <iostream>
using namespace std; int a = 0; int main() {
string a = "1";
cout << a << endl; // 在main函数体内找到了a的声明,停止名字查找,输出为string的内容“1”
return 0;
}

名字查找还受到作用域限定符::的影响,若变量之前出现了作用域限定,那么则会从限定的作用域内进行全局搜索,并且不会查找其他位置。如果::之前没有出现作用域名,那么就会在全局作用域查找。

#include <iostream>
using namespace std; int a = 0; int main() {
string a = "1";
cout << ::a << endl; // 限定a的查找从全局作用域开始,那么首先被找到的是a的int类型定义,程序输出0
return 0;
}

此外,由于在找到同名声明之后便会停止查找,函数匹配出现在名字查找之后

#include <iostream>
using namespace std; void print() { cout << "1" << endl; } int main() {
int print;
print(); // 试图调用print(),但程序无法通过编译,这是因为在找到int型变量print之后,
// 编译器就停止了查找,把一个变量当作函数调用显然是错误的
return 0;
}

名字隐藏

从上面的例子可以看出,在不使用访问限定符的情况下,内层作用域的变量会隐藏外层作用域的同名变量,即发生了名字隐藏。名字隐藏还会发生在类的继承过程,在子类定义和父类同名的成员时,会隐藏从父类继承来的成员,名字隐藏并不是什么特性,相反,名字隐藏会增加程序编写的难度。我们应该养成良好的命名习惯,避免出现名字隐藏

最佳匹配

在函数调用时,首先对函数进行名字查找,在找到一个同名函数(假设不会出现命名冲突)时,编译器并不会停止查找,而是继续找出当前作用域的所有重载函数,然后根据最佳匹配规则,确定实际调用的函数。不同作用域的同名函数并不会被视为重载。最直观的例子是,类内的函数与类外的同名函数并不会形成重载。

在名字查找完成且不存在编译错误的情况下,编译器便开始确定与调用匹配得最好的函数。最佳匹配原则也很简单,实参类型与形参类型越接近,匹配得越好。

void print(int a) { cout << "int" << endl; }

void print(double a) { cout << "double" << endl; }

print(1); // 1是int类型,与print的int形参重载构成最佳匹配,故程序输出“int”

但如果同时有多个函数与调用形成匹配,那么编译器将报错。编译器不允许有二义性的调用存在。

void print(int a, int b, int c) { cout << "int" << endl; }

void print(double a, double b, double c) { cout << "double" << endl; }

print(1, 1.0, 1); // 编译器指出有多个函数重载匹配

C++:Name Lookup & Best Match的更多相关文章

  1. Mongodb:修改文档结构后出现错误:Element '***' does not match any field or property of class ***.

    Mongodb:修改文档结构后出现错误:Element '***' does not match any field or property of class ***. Mongodb是一种面向文档的 ...

  2. ElasticSearch查询 第四篇:匹配查询(Match)

    <ElasticSearch查询>目录导航: ElasticSearch查询 第一篇:搜索API ElasticSearch查询 第二篇:文档更新 ElasticSearch查询 第三篇: ...

  3. fastDfs V5.02 升级到 V5.08版本后,启动报错:symbol lookup error: /usr/bin/fdfs_trackerd: undefined symbol: g_current_time

    /libfastcommon-1.0.36 # ./make.sh cc -Wall -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -g -O3 -c -o hash.o ...

  4. Neo4j 第九篇:查询数据(Match)

    Cypher使用match子句查询数据,是Cypher最基本的查询子句.在查询数据时,使用Match子句指定搜索的模式,这是从Neo4j数据库查询数据的最主要的方法.match子句之后通常会跟着whe ...

  5. 记录一次(xheditor-1.1.6-zh-cn.min.js)的错误:Cannot read property 'match' of undefined的问题解决

    由于使用了xheditor富文本框,且这个版本是2011年开发的系统,当时只有IE8,所以一切正常. 但是问题来了,今天使用IE11测试和谷歌浏览器测试,发现一直报这个错误: 且google了一下,没 ...

  6. Python自动化报错:IndentationError-unindent does not match any outer indentation level

    ​从错误中了解python语法: 如下图: 这个是因为python语句块是由格式来控制(缩进): 解决: 出现这个问题需要看下,自己写的python语句块是否格式缩进的问题 例如:如下图:构造函数前面 ...

  7. IndentationError:unexpected indent”、“IndentationError:unindent does not match any outer indetation level”以及“IndentationError:expected an indented block Python常见错误

    错误的使用缩进量 记住缩进增加只用在以:结束的语句之后,而之后必须恢复到之前的缩进格式. 经典错误,一定要注意缩进,尤其是在非界面化下环境的代码修改

  8. 错误: symbol lookup error: /usr/local/lib/libreadline.so.6: undefined symbol: PC

    su - root mkdir temp mv /local/ldconfig  apt-get update

  9. python正则表达式模块re:正则表达式常用字符、常用可选标志位、group与groups、match、search、sub、split,findall、compile、特殊字符转义

    本文内容: 正则表达式常用字符. 常用可选标志位. group与groups. match. search. sub. split findall. compile 特殊字符转义 一些现实例子 首发时 ...

随机推荐

  1. 使用paramiko模块进行封装,远程操作linux主机

    import time import paramiko class HandleParamiko: ''' 定义一个linux处理类 ''' def __init__(self, hostname, ...

  2. 对并发Map的测试

    /** * ConcurrentHashMap效率最高 */ public class MapTest { public static void main(String[] args) throws ...

  3. Redis for OPS 01:关于 Redis 基础说明与安装部署

    写在前面的话 本章节开始在主要介绍在运维工作中绕不开的一个话题,数据缓存 NoSQL 服务 Redis,搭建很简单,使用很简单,运行也稳定的一批,一般小公司几乎很少出现以为量的问题导致他 down 掉 ...

  4. .net core 的 aop 实现方法汇总

    decorator 不借助第三方DI容器,通过装饰模式通过内置的DI容器实现 https://medium.com/@willie.tetlow/net-core-dependency-injecti ...

  5. 常见跨域解决方案以及Ocelot 跨域配置

    常见跨域解决方案以及Ocelot 跨域配置 Intro 我们在使用前后端分离的模式进行开发的时候,如果前端项目和api项目不是一个域名下往往会有跨域问题.今天来介绍一下我们在Ocelot网关配置的跨域 ...

  6. 从新手小白到老手大白的成长之路第二弹-WPF之UI界面之Grid面板

    废话不多说,接下来直接开始介绍WPF-UI界面-Grid面板 如图就是创建好了的一个WPF项目,整个界面被一个Window窗体包含起来,上面类似于什么什么网址什么的其实就相当于.net的命名空间,缺什 ...

  7. gzip格式分析与识别

    " 介绍gzip格式,识别gzip压缩的数据流量." 在协议分析过程中,经常会发现gzip压缩的数据,例如在HTTP协议中,在HTTP头中会标示,内容编码为gzip.DEFLATE ...

  8. Gradle使用的简单了解

    Gradle 认识 参考博客:http://www.enjoytoday.cn/categorys/Gradle gradle是一个用于构建工程的工程配置脚本,它可以很便捷的帮助我们构建管理工程结构, ...

  9. netcore codefirst生成数据库命令

    1.程序通过nuget安装包 Microsoft.EntityFrameworkCore.Design 2.生成添加脚本 add-migration InitialCreate -Context AL ...

  10. 使用maven-compiler-plugin以及maven-shade-plugin完成maven项目打包

    最近负责一个纯maven项目(项目需求尽量轻量化),需要自己完成打包工作. 因此,基于maven-compiler-plugin以及maven-shade-plugin完成项目的打包工作. 其中: m ...