5

C++ では、ネストされた匿名名前空間を次の方法で宣言することは合法です。

namespace {
    namespace {
        struct Foo
        {
        };
    }
}

namespace {    
    struct Foo // SAME IDENTIFIER AS <unnamed>::<unnamed>::Foo!!!
    {
    };
}

しかし、あいまいさを避けるために、明示的に型指定された Foo を使用して識別子を宣言するにはどうすればよいでしょうか?

編集済み - 質問を読んでいない皆さんへ。

ps この種の構造を使用するつもりはありませんが、誰かが Foo の正当な使用法を見つけた場合に備えて、Foo を明確にすることができるかどうかを理解する必要があります。私のコンパイラ拡張機能は、すべてのケースを処理する必要があります。

4

2 に答える 2

4

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 unique1Foousing namespace unique3;私は間違っていた。以下のコメントにより修正されました。

次に、7.3.4p4 から:

非修飾ルックアップ (3.4.1) の場合、using ディレクティブは推移的です。スコープに、それ自体が using ディレクティブを含む 2 番目の名前空間を指定する using ディレクティブが含まれている場合、その効果は、2 番目の名前空間からの using ディレクティブも同様です。最初に登場。

したがって、 を参照する場合、 または のいずれかFooを意味する可能性がありますが、これはエラーです。他の答えが言うことに注意してください: . これは正しくありません。using ディレクティブによりアクセスできます。両方の名前が表示されるだけです。unique1::unique2::Foounique3::Foohas 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

于 2012-10-25T23:59:23.660 に答える
0

はい、これは何にも矛盾しないため、完全に合法です。

名前のない名前空間は、概念的には次のものと同等です。

namespace <09FD8E6E-2DB6-4517-B62D-3B5A657DCC82>
{
  // ....
}

名前のない各名前空間には、アクセスできない固有の名前が隠されていることを意味します。

于 2012-10-25T23:40:06.517 に答える