提问人:ThomasMcLeod 提问时间:9/21/2012 最后编辑:ThomasMcLeod 更新时间:9/22/2012 访问量:1196
c++ using 指令的作用域
Scope of the c++ using directive
问:
摘自 c++11 标准的第 7.3.4.2 节:
using 指令指定指定命名空间中的名称 可以在 using 指令出现在 之后的作用域中使用 using 指令。在非限定名称查找 (3.4.1) 期间,名称 看起来好像它们是在最近的封闭命名空间中声明的 它包含 using 指令和指定的命名空间。[ 注:在此上下文中,“包含”是指“直接包含或 间接”。——尾注 ]
第二句和第三句到底是什么意思?请举例说明。
这是我试图理解的代码:
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;
}
它打印“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;
}
标准的含义是在线
int tmp = i + 11;
该名称出现在“最近的封闭命名空间中,其中包含 using 指令和指定的命名空间”;using 指令出现在 而指定的命名空间为 ;最接近的封闭命名空间是全局命名空间,因此显示为 。这意味着,如果名称已存在于全局命名空间中,则代码不明确。i
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;
}
}
}
在 行 中,出现在 using 指令(即 )和指定的命名空间 () 的最近封闭命名空间中,即 。因此,在 using 指令之后的 within 中,以及 在 中,非限定名称可以指显示为 , shadowing any , 与 any 冲突 , 并被 any 或 (within ) 遮蔽:int j = i
i
A::D
A::B::C
A
A::D
A::D::E
i
A::B::C::i
A::i
::i
A::i
A::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;
}
}
}
请注意,仅仅因为该名称在非限定名称查找期间显示,并不意味着它确实存在;限定名称将继续仅引用实际名称(如果存在)。A::i
A::i
A::i
评论
int j = i
i
int i = 5;
int i = 6;
i
int j = i;
A::D::i
A::D::E::i
int j = i
i
A::D::i
A::D::E::i
评论
i
namespace B
A::i
A::i
using namespace A
i
i
A