使用指令与使用声明
Using directive vs using declaration
你能解释一下为什么这段代码有效并打印 16;
#include <iostream>
namespace X {
int p = 5;
}
namespace Y {
int p = 16;
using namespace X;
}
int main()
{
std::cout << Y::p;
}
以及为什么此代码会抛出多个声明的错误
#include <iostream>
namespace X {
int p = 5;
}
namespace Y {
int p = 16;
using X::p;
}
int main()
{
std::cout << Y::p;
}
我听说使用指令不仅仅是使用任何名称声明的过程,因为它似乎的工作方式不同
但我不明白为什么,你能给出一些详细的解释吗?
同样,这个可以很好地打印 16,如果我只用 X::p 的声明替换使用该指令,它将抛出相同的错误
#include <iostream>
namespace X {
int p = 5;
}
int p = 16;
using namespace X;
int main()
{
std::cout << ::p;
std::cout << "n";
return 0;
}
关键的区别在于,use 声明就是声明。而使用指令不是。我知道这听起来很愚蠢,但这就是差异的本质。前者实际上将声明添加到声明性区域,而后者仅使某些名称在声明性区域中可用。
使名称在特定范围内可用,而不是声明它,旨在成为一件更弱的事情。如果存在另一个具有相同名称的声明,则在限定查找期间不考虑前者,如 [basic.scope.hiding]/4 所示:
在查找由命名空间名称限定的名称期间, 否则由using-指令可见的声明可以被命名空间中具有相同名称的声明隐藏 包含using-指令
这几乎解释了你的第一个代码片段。由于 using 声明,该名称有一个声明,因此不考虑由 using 指令显示的名称。不管哪个先来,宣言总是更有力。
您的第二个代码片段有两个声明,用于Y
中的p
。当涉及到这些时,通常的声明规则适用。第二个必须声明相同的内容,否则程序格式不正确。仅此而已,真的。
最后,在第三个代码片段中,它与第一个代码片段中的代码片段更相似。[basic.lookup.qual]/4 是这样说的:
以一元作用域运算符
::
([expr.prim]) 为前缀的名称为 在全局范围内查找,在使用它的翻译单元中查找。 该名称应在全局命名空间范围内声明,或者应为 其声明在全局范围内可见的名称,因为using-directive([namespace.qual]).使用::
允许全局 要引用的名称,即使其标识符已被隐藏。
因此,除了要查找的命名空间之外,其他所有内容都与您的第一个示例一样。你们都声明它,并通过 using 指令使其可用。我引用的第一段决定了必须选择哪一段。
- .cpp和.h文件中的模板专用化声明
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 未在作用域中声明unordered_map
- C++避免重复声明的语法是什么
- 如何确保C++函数在定义之前声明(如override关键字)
- 无法编译 rtmidi 测试 cmidiin.cpp 文件, 非法指令
- 错误:未在此范围内声明'reverse'
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 为什么在定义函数之前先声明它
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- #ifdef和未声明的标识符
- 在一个指令中声明更多指针的运算符优先级
- 为什么名称查找在找到使用 using 指令隐式声明的实体时不停止?
- 使用指令与使用声明
- C :使用声明和指令的顺序会影响选择
- C++中include指令和forward声明之间的区别
- 全局变量外部声明后的线程专用指令
- 通过 using-指令在 using-声明中进行名称查找
- OpenMP对性能的影响:私有指令vs.在构造中声明变量
- 在最近的封闭范围内使用using指令声明局部外部变量