消除了不確定的行爲:
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-的「最近的封閉命名空間中的名稱指令和指定命名空間「; 使用指令出現在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
出現在使用指示符(即,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
)被遮擋的:僅僅因爲名字不合格的名稱查找過程中會顯示爲A::i
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
(如果存在)。
此處的行爲未定義。 'namespace B'中的兩個'i'實例指向同一個變量(只要它的* declarator *被看到,即在初始化之前,它就會影響'A :: i')。所以它被初始化時自己的垃圾值增加了11. –
好的,爲什麼它會在'使用命名空間A'之後影響'A :: i'。這是標準中的段落在談論什麼? – ThomasMcLeod
@ThomasMcLeod:這就是陰影*意味着*:隱藏了一個定義。由於您沒有限定在表達式中使用'i',因此無法查找。由於C++允許你引用你剛纔定義的變量,所以即使在初始化表達式中,'i'將是新的,而不是'A'中的。 –