Tho*_*eod 4 c++ standards namespaces using-directives c++11
从c ++ 11标准的7.3.4.2节:
一个using指令规定,在被提名的命名空间中的名字可以在该范围内使用using指令后出现using指令.在非限定名称查找(3.4.1)期间,名称看起来好像是在最近的封闭命名空间中声明的,其中包含using-directive和指定的命名空间.[注意:在此上下文中,"包含"表示"直接或间接包含". - 尾注]
第二句和第三句完全是什么意思?请举例.
这是我试图理解的代码:
namespace A
{
int i = 7;
}
namespace B
{
using namespace A;
int i = i + 11;
}
int main(int argc, char * argv[])
{
std::cout << A::i << " " << B::i << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
正如我所料,它打印"7 7"而不是"7 18".
抱歉打印错误,该程序实际打印"7 11".
using代码中的语句无关紧要.B::i已B::i评估初始化程序时的范围.你可以通过删除using声明来简单地证明这一点; 你的代码应该编译和运行相同.在任何情况下,B::i最终都是未定义的值,因为它取决于未初始化的值(即B::i评估初始化程序时的值).
消除未定义的行为:
namespace A
{
int i = 7;
}
namespace B
{
using namespace A;
int tmp = i + 11;
int i = tmp;
}
#include <iostream>
int main()
{
std::cout << A::i << " " << B::i << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该标准的含义是在该行
int tmp = i + 11;
Run Code Online (Sandbox Code Playgroud)
该名称i出现在“最近的封闭命名空间,其中包含 using 指令和指定命名空间”;using -directive出现在,namespace B而指定的命名空间是namespace A; 最近的封闭命名空间是全局命名空间,因此i显示为::i。这意味着如果名称i已存在于全局命名空间中,则代码是不明确的。
对于更复杂的示例:
namespace A {
namespace B {
namespace C {
int i = 4;
}
}
namespace D {
using namespace B::C;
namespace E {
int j = i;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在行 处int j = i,i出现在 using 指令(即A::D)和指定命名空间(A::B::C)的最近封闭命名空间中,即A。因此,在A::Dusing 指令之后,以及在 中A::D::E,非限定名称i可以指A::B::C::i出现为A::i、遮蔽 any ::i、与 any 冲突A::i以及被 anyA::D::i或遮蔽A::D::E::i(在 内A::D::E):
int i = 1; // shadowed by A::B::C::i appearing as A::i
namespace A {
int i = 2; // conflicts with A::B::C::i appearing as A::i
namespace B {
int i = 3; // irrelevant
namespace C {
int i = 4; // nominated; appears as A::i
}
}
namespace D {
int i = 5; // shadows A::B::C::i appearing as A::i
using namespace B::C;
namespace E {
int i = 6; // shadows A::B::C::i appearing as A::i
int j = i;
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,仅仅因为该名称在非限定名称查找期间显示为 A::i,并不意味着它实际上存在。限定名称A::i将继续仅指实际名称A::i(如果存在)。