未定義の動作を排除する:
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::Dusing ディレクティブの後、および 内A::D::Eでも、非修飾名iは、A::B::C::iとして表示されることA::i、 any をシャドウすること、 any::iと競合すること、および anyまたは( 内で)A::iによってシャドウされることを参照できます。A::D::iA::D::E::iA::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::iA::i