C++ 標準では、7.3.1.1p1 でかなり明確に述べられています。
unnamed-namespace-definition は、
inline(opt) namespace unique { /* empty body */ }
using namespace unique ;
namespace unique { namespace-body }
inline は、unnamed-namespace-definition に出現する場合にのみ出現し、翻訳単位内のすべての一意の出現は同じ識別子に置き換えられ、この識別子はプログラム全体の他のすべての識別子とは異なります。
上記から、コードが実際に次のように変換されることがわかります。
namespace unique1 {}
using namespace unique1;
namespace unique1 {
namespace unique2 {}
using namespace unique2;
namespace unique2 {
struct Foo
{
};
}
}
namespace unique3 {}
using namespace unique3;
namespace unique3 {
struct Foo
{
};
}
したがって、1つ目は内でのみFoo
アクセスでき、2 つ目は によりグローバル名前空間でアクセスできます。namespace unique1
Foo
using namespace unique3;
私は間違っていた。以下のコメントにより修正されました。
次に、7.3.4p4 から:
非修飾ルックアップ (3.4.1) の場合、using ディレクティブは推移的です。スコープに、それ自体が using ディレクティブを含む 2 番目の名前空間を指定する using ディレクティブが含まれている場合、その効果は、2 番目の名前空間からの using ディレクティブも同様です。最初に登場。
したがって、 を参照する場合、 または のいずれかFoo
を意味する可能性がありますが、これはエラーです。他の答えが言うことに注意してください: . これは正しくありません。using ディレクティブによりアクセスできます。両方の名前が表示されるだけです。unique1::unique2::Foo
unique3::Foo
has hidden unique name that cannot be accessed
ただし、スコープ解決演算子::
を先頭に追加すると、次の理由でアクセスFoo
できます。unique3::Foo
3.4.3.2p2 から:
名前空間 X と名前 m の場合、名前空間で修飾されたルックアップ セット S(X,m) は次のように定義されます。 7.3.1)。S0(X,m) が空でない場合、S(X,m) は S0(X,m) です。それ以外の場合、S(X,m) は、X の using ディレクティブによって指定されたすべての名前空間 Ni とそのインライン名前空間 set の S(Ni,m) の和集合です。
強調された部分はusing-directives in X
、あなたの場合はusing namespace unique1;
andusing namespace unique3;
を意味するため、名前空間で修飾されたルックアップ セットは次のようになります:はセットに含まれていないため、エラーではありませんS(unique3::Foo)
。unique1::unique2::Foo