消除未定义的行为:
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;
该名称i
出现在“最近的封闭命名空间中,其中包含使用指令和指定的命名空间”;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;
}
}
}
在行int j = i
,i
出现在 using 指令(即A::D
)和指定的命名空间(A::B::C
)最近的封闭命名空间中,即A
. 因此,在A::D
using 指令之后的 inside 以及 inside A::D::E
,非限定名称i
可以指A::B::C::i
出现为A::i
、遮蔽 any ::i
、与 any 冲突A::i
以及被 anyA::D::i
或A::D::E::i
(within 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
(如果存在)。