经实验验证,修正对using namespace std的认识
备注①: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 ;
}
经实验验证,修正对using namespace std的认识的更多相关文章
- using namespace std 和 using std::cin
相较using std::cin使用using namespace std不会使得程序的效率变低,或者稳定性降低,只是这样作会将很多的名字引入程序,使得程序员使用的名字集合变小,容易引起命名冲突. 在 ...
- namespace std
c++中使用namespace来防止命名冲突(重命名),我们经常使用的一些函数和变量都被放在一个叫std的namespace中,如标准I/O流操作,vector等等.我们在每一个文件中都可使用std中 ...
- C++ using namespace std(转载)
转载自http://www.kuqin.com/language/20080107/3532.html 感谢这位大神的解答! 以下的内容摘抄自转载的文章里面的部分内容. 早些的实现将标准库功能定义在全 ...
- 不要在头文件中使用 using namespace std;
不要在头文件中使用(using namespace std;). 若你使用了using namespace std;,在某一头文件中,那么包含这些头文件的文件就失去了"namespace ...
- using namespace std
using namespace std std 是一个命名空间..不同的命名空间可以有相同的类名被定义 ..using namespace std;就是指明下面的程序使用std,如果不用这句指明的话就 ...
- #include<iostream.h>与#include<iostream> using namespace std的区别
所谓namespace,是指标识符的各种可见范围.C++标准程序库中的所有标识符都被定义于一个名为std的namespace中. 一 :<iostream>和<iostream.h ...
- 关于using namespace std
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~关于using namespace std ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...
- 实验验证sys和system用户全库导出的区别
我们在做逻辑数据泵全库导出的时候,有两种流行的写法,一种是sys用户导出,一种是使用system用户导出. 现在想知道二者之间有什么区别?实验验证之前不妨先思考一下: sys和system用户的权限区 ...
- 有多个.h引用时,不能有using namespace std
#include<iostream.h> #include<math.h> //using namespace std; 有多个.h引用时,不能有这个,否则无法运行. void ...
随机推荐
- update的where条件要把索引的字段带上,要不然就全表锁
update的where条件要把索引的字段带上,要不然就全表锁 文章目录 update的where条件要把索引的字段带上,要不然就全表锁 本文主要内容 背景 ...
- 通过async与await实现高效并发
withTimeoutOrNull: 在上一次https://www.cnblogs.com/webor2006/p/12010388.html中对于协程的超时机制进行了一个学习,上次用的是withT ...
- isaster(Comet OJ - Contest #11D题+kruskal重构树+线段树+倍增)
目录 题目链接 思路 代码 题目链接 传送门 思路 \(kruskal\)重构树\(+\)线段树\(+\)倍增 代码 #include <set> #include <map> ...
- 用Python玩转微信
Python玩转微信 大家每天都在用微信,有没有想过用python来控制我们的微信,不多说,直接上干货! 这个是在 itchat上做的封装 http://itchat.readthedocs.io ...
- actuator beans不展示
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...
- 修改Discuz!X系列开启防CC攻击,不影响搜索引擎收录
最近网站一直被攻击,特别是新上线的交流社区,所以今天写了一个开启CC攻击防护代码,而且不影响搜索引擎收录. 在config_global.php文件中有如下代码: $_config['security ...
- N种自动化测试框架(包含自动化和性能,总有一款适合你)
不知不觉,分享的框架已经6个了(准确说应该是4个),仅仅是接口的. 这些框架都是最基础的框架,需要根据实际使用场景进行完善,大家就当练手实践吧. 不需要写代码的自动化框架 JMeter + Ant+ ...
- 【java异常】Expected one result (or null) to be returned by selectOne(), but found: 63
OmQuotaTBBean omQuotaTBBean = mOmQuotaTBMapper.findOmQuotaTB(); 改成 List<OmQuotaTBBean> listOmQ ...
- 安装PyInstaller失败
pip install PyInstaller 报错: 后运行: 指定安装源进行安装: pip3 install pyinstaller -i https://pypi.doubanio.com/si ...
- 【CSP-S膜你考】 A
A 题面 对于给定的一个正整数n, 判断n是否能分成若干个正整数之和 (可以重复) , 其中每个正整数都能表示成两个质数乘积. 输入格式 第一行一个正整数 q,表示询问组数. 接下来 q 行,每行一个 ...