c++ - using 指令如何以及在何处注入成员名称?
问题描述
AFAIK using 指令在最近的封闭命名空间中公开或注入命名空间的所有名称。这是来自 C++ 入门:
相反, using 指令使命名空间的全部内容都可用 通常,命名空间可能包含不能出现在本地范围内的定义。因此,using 指令被视为出现在最近的封闭命名空间范围内。
在最简单的情况下,假设我们有一个命名空间 A 和一个函数 f,它们都定义在全局范围内。如果 f 对 A 有 using 指令,那么在 f 中,就好像 A 中的名称出现在 f 的定义之前的全局范围内
并来自 cppreference:
- using-directive:从 using-directive 之后的任何名称的非限定名称查找的角度来看,直到它出现的范围结束,来自 ns_name 的每个名称都是可见的,就好像它是在最近的封闭命名空间中声明的一样包含 using-directive 和 ns_name。
#include <iostream>
int x = 1;
int y = 2;
int z = 3;
namespace A{
namespace B{
int x = 5;
int y = 10;
int z = 0;
}
void foo(){
using namespace A::B;
std::cout << x << '\t' << y << '\t' << z << '\n'; // x, y, z are not ambiguous
}
}
namespace AA{
namespace BB{
void bar(){
using namespace A::B;
std::cout << x << '\t' << y << '\t' << z << '\n'; // x, y, z are ambiguous
}
}
}
int main(){
A::foo(); // works fine
AA::BB::bar(); // fails to compile
std::cout << "\ndone!\n";
}
为什么第一个版本可以正常工作(function
A::foo()
)但第二个版本(AA::BB::bar()
)不行?我发现“将名称注入到 using 指令和命名空间定义的最近命名空间中”有点令人困惑。
解决方案
是的,这很令人费解,但你给出的报价准确地解释了发生了什么。在您的第一个示例中(将变量数量减少到 1):
int x = 1;
namespace A {
namespace B {
int x = 5;
}
void foo(){
using namespace A::B;
std::cout << x << '\n';
}
}
最近的命名空间是A
. 本质上,代码相当于
int x = 1;
namespace A {
int x = 5;
void foo(){
std::cout << x << '\n'; // x from NS a.
}
}
x
将是在 A 中定义的名称并将被使用。
在第二个例子中,
namespace AA {
namespace BB {
void bar() {
using namespace A::B;
std::cout << x << '\n';
}
}
}
最近的命名空间将是全局命名空间。本质上,代码相当于
int x = 1;
int x = 5;
namespace AA {
namespace BB {
void bar() {
std::cout << x << '\n';
}
}
}
此代码格式错误,因为x
无法在同一范围内重新定义。
推荐阅读
- c++ - 如何检查表达式是否是函数名?
- php - 如何使用 fetch 函数从数据库中获取的数据只获取一个值
- cakephp - HasOne 关联表未保存
- wordpress - 如何在wordpress rest api中过滤自定义帖子类型的自定义字段?
- bash - 完成第一个循环后,循环退出的 Shell 脚本
- javascript - 下划线 js - Uncaught SyntaxError: Unexpected token if
- javascript - 近似的平方根
- python - 如何使用 Django Rest Framework 将多个模型序列化为一个序列化器以实现层次结构?
- java - 防止变量在运行结束后重置
- r - 如何修复此意外令牌“!=”错误