2

これは、C++ 標準に従って、整形式または整形式ですか?

namespace M { struct i {}; }
namespace N { static int i = 1; }
using M::i;
using N::i;
int main() { sizeof (i); }

Clang はそれを拒否し、GCC はそれを受け入れます。

[namespace.udir-6] ( http://eel.is/c++draft/basic.namespace#namespace.udir-6 ) によると:

名前検索で 2 つの異なる名前空間で名前の宣言が検出され、宣言が同じエンティティを宣言せず、関数も宣言されていない場合、その名前の使用は不適切です。

これをどのように解釈すべきでしょうか。各 using 宣言は [namespace.udecl]p1 ( http://eel.is/c++draft/namespace.udecl#1 )によって名前を宣言していることに注意してください。

using 宣言は、using 宣言が現れる宣言領域に名前を導入します。

using-declaration :ネストされた名前指定子の非修飾 IDを
   using typename選択します ;

using宣言で指定されたメンバー名は、using宣言が現れる宣言領域で宣言されます。[ 注: 指定された名前のみがそのように宣言されています。using-declaration で列挙名を指定しても、using-declaration の宣言領域でその列挙子が宣言されません。— 終わりの注 ] using 宣言がコンストラクター ([class.qual]) を指定する場合、using 宣言が現れるクラス ([class.inhctor]) 内のコンストラクターのセットを暗黙的に宣言します。それ以外の場合、using-declaration で指定された名前は、別の名前空間またはクラスの一連の宣言の同義語です。

したがって、名前 i の 4 つの宣言があります。

これらのうち、非修飾名検索で検索されるのはどれiですかsizeof(i)?

プログラムが整形式であるように、同じ名前空間 (グローバル名前空間) にあるusing M::i;とだけを見つけますか?using N::i;

それとも、異なる名前空間にある と だけを見つけstruct i {};static int i = 1;、プログラムの形式が正しくないのでしょうか?

または、他の代替手段がありますか?

4

2 に答える 2

1

ボグダンはすでに答えを持っていますが、あなたの直感が間違っている理由に基づいて、あなたは次のように引用しました:

名前検索で2 つの異なる名前空間で名前の宣言が検出され、宣言が同じエンティティを宣言しておらず、関数を宣言していない場合、その名前の使用は不適切です。

ただし、この例では次のようになります。

namespace M { 
    struct i {};           // declares M::i, entity class type
}
namespace N { 
    static int i = 1;      // declares N::i, entity variable
}
using M::i;                // declares ::i, synonym of M::i
using N::i;                // declares ::i, synonym of N::i
                           // hides (*) the other ::i
int main() { 
    sizeof (i); 
}

について詳しく説明すると、グローバル名前空間に の(*)2 つの宣言があります。[basic.scope.hiding] から:i::

クラス名 (9.1) または列挙名 (7.2) は、同じスコープで宣言された変数、データ メンバー、関数、または列挙子の名前によって非表示にすることができます。クラスまたは列挙名と、変数、データ メンバー、関数、または列挙子が同じスコープで (任意の順序で) 同じ名前で宣言されている場合、クラスまたは列挙名は、変数、データ メンバー、関数、または列挙子名が表示されます。

したがって、2 つiの が同じスコープにある場合、クラスは隠され ( using 宣言の順序に関係なく!)、のシノニムである を参照します。両方の が同じ名前空間 ( ) にあったため、引用は当てはまりません。これは、代わりにusing-directivesがあった以前の質問とは異なります。sizeof(i)::iN::ii::

using namespace M;
using namespace N;

i2 つの異なる非機能エンティティを参照して、2 つの異なる名前空間に存在します。したがって、エラー。ここでは、Clang が間違っていて、GCC が正しいです。

于 2015-07-29T21:42:45.217 に答える