备注①:name:符号。指的实体包括:变量、函数、类

备注②:认为全局命名空间也是一个包,在此称作 ROOT:: 或 global::

(这样就有了两个特别的包:一个是全局包,一个是std包。但对于编译器(pack-path. names模型)来说,它们和用户自定义的namespace没有区别)


修正1. global::(全局包)中的names,并不都是用户自定义的。

2.   两条重要认识,以及由此解释一些之前的问题

一、using namespace xxx; <—> using pack-A的本质作用:   相当于把 导入的Pack-A的 names 移到 using pack-A;  这行文字所在的那个namespace   的names空间里。

二、所有非ROOT 的namespace里 ,都已默认存在 using namespace ::  (移入了ROOT包的 names ) ——>  所以才直接用全局的names

结论1:之前都是 "using namespace std "写在自定义namespace外,那么这行处在global::中,导致:把引进来的std::包里的names移到了 global包,成为全局的名字。

又因为各namespace已默认导入了global::names,所以这部分std::names进入了各namespace里。

导致的问题: 这样,当在wjh::内写某个name的定义时,若未加namespace-xxx::前缀而直接引用了 ‘fuck’,那么这个fuck可能有3处来源:

①wjh::fuck

②(global::) fuck

③namespace-ABC::fuck    //     在全局(=namespace外部) 中using namespace ABC后, ABC::下的names进入全局空间,进一步进入wjh::

只要以上3个namespace里存在不止一个 fuck 这个name,就属于 ‘Ambiguous function call’ 报错。 (也可能不报错,但编译器会自己挑一个合适的用!)

不存在什么优先认定,3个中只能存在1个!

     /*

*    ↑   修正:实验了一下,当不加包路径的 fuck存在上面①②③时,确实会选择①、编译器不提示报错。 所以同namespace的那个name确实是优先的

*         但当同namespace下无此name,②③是会冲突的。

*/

结论2:所以using namespace std; 为什么不能使用?

别人的模块引用了你的这个头文件后,多了这行字,原来未加namespace:: 引用的name只有一处定义,现在可能就多了个定义,

而编译器又不报错,就导致‘God knows what’种种奇特行为(因为引用的name被偷偷替换掉了)


写段实验代码验证一下以上认识:

   前提:<test.h> :  定义一个global::fuckit();    在namespace wjh{ }里也定义一个fuckit(); 

观察:此时在wjh{ } 中引用 fuckit()  (不加wjh::),看是否提示


#ifndef _TRIAL_1_H
#define _TRIAL_1_H

int fuckit();

namespace wjh {
   int fuckit();
}
#endif


在global::下使用如下 (该main位于global空间)

(using namespace wjh;  把 wjh::fuckit 这个name移入了global::中)

#include "trial-1.h"

using namespace wjh;

int main() {
::fuckit();
wjh::fuckit();
fuckit(); //报错! system("pause");
return ;
}

截图如下:


更进一步的实验:

 #ifndef _TRIAL_1_H
#define _TRIAL_1_H // ③ s_t_d::fuckit
namespace s_t_d {
int fuckit();
} // ② (global::) fuckit
int fuckit(); // ① wjh::fuckit
namespace wjh {
using namespace s_t_d;
int fuckit();
void call_fuckit();
} #endif
 #include "trial-1.h"

 #include <iostream>
#include <cstdlib> //using namespace s_t_d;
//using namespace wjh; int s_t_d::fuckit() {
std::cout << "s_t_d:: fuckit" << std::endl;
return ;
}
int fuckit() {
std::cout << "global:: fuckit" << std::endl;
return ;
}
int wjh::fuckit() {
std::cout << "wjh:: fuckit" << std::endl;
return ;
} void wjh::call_fuckit() {
using namespace s_t_d;
std::cout << "running in wjh:: calling fuckit ..." << std::endl;
fuckit();
} int main() {
wjh::call_fuckit(); fuckit(); system("pause");
return ;
}

最新文章

  1. C语言 01 形参实参
  2. 【Android】[转] Android Handler应设为static
  3. win8.1企业版 IIS8.5 安装php5.5.18详细图文
  4. delphi常用快捷键(我自己经常使用的)
  5. Synchronization in Delphi TThread class : Synchronize, Queue
  6. 【memcache缓存专题(2)】memcache安装与命令行使用
  7. Android自定义控件步骤总结
  8. iOS 沙盒目录结构介绍
  9. C#基础语法总结
  10. Vmware linux 安装 Vmware Tools 提示只读
  11. random_shuffle (stl算法)打乱顺序 - 飞不会的日志 - 网易博客
  12. windos环境apache+mysql+php+Discuz的安装配置
  13. JSON 解析工具的封装(Java)
  14. GIT入门笔记(3)- git中的一些概念和原理
  15. Python面向对象 组合(选课系统示例)
  16. rabbitMQ、activeMQ、zeroMQ、Kafka、Redis 比较
  17. 深入理解 Neutron -- OpenStack 网络实现(1):GRE 模式
  18. mysql 管理脚本
  19. 统计学习方法c++实现之七 提升方法--AdaBoost
  20. 20181101noip模拟赛T1

热门文章

  1. Nginx 反向代理功能-实现Nginx tcp负载均衡
  2. Linux操作系统安全-局域网私有CA(Certificate Authority)证书服务器实战篇
  3. 浅析Volatile关键字
  4. Python 实现基于信息熵的 ID3 算法决策树模型
  5. isaster(Comet OJ - Contest #11D题+kruskal重构树+线段树+倍增)
  6. Gartner:2019 年 iPaaS 魔力象限
  7. stm32定时器频率采样的方式
  8. 函数$f(x+1)$和$f(x-1)$的奇偶性
  9. GDAL在VS下配置测试
  10. Android Q Beta 6 终极测试版发布!