未定義の動作を排除する:
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 ディレクティブと指定された名前空間の両方を含む、最も近い囲み名前空間」に表示されます。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
、using ディレクティブ (つまりA::D
) と指定された名前空間 ( ) の最も近い囲み名前空間 ( A::B::C
) に表示されますA
。したがって、A::D
using ディレクティブの後、および 内A::D::E
でも、非修飾名i
は、A::B::C::i
として表示されることA::i
、 any をシャドウすること、 any::i
と競合すること、および anyまたは( 内で)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