web-dev-qa-db-ja.com

ネストされた名前指定子の不完全な型

次のように、ネストされた名前指定子で不完全な型を使用しようとしました。

class A;

int b= A::c; // error: incomplete type ‘A’ used in nested name specifier

class A {
    static const int c=5;
};

N3797ワーキングドラフトの3.4.3/1には、それについて何も記載されていません。

クラス、名前空間のメンバーまたは列挙子の名前は、そのクラス、名前空間、または列挙を示すネストされた名前指定子に適用される::スコープ解決演算子(5.1)の後に参照できます。

それで、その動作の実装は依存していますか?

34
user2953119

前書き

標準には、コードが不正な形式であることを暗黙的に暗示しているいくつかの場所がありますが、以下の引用はそれ自体を表しています:

3.3.2p6宣言のポイント[basic.scope.pdecl]

クラスメンバの宣言ポイントの後、そのクラスのスコープ内でメンバ名を検索できます。

コードの問題は、不完全な型の本体の内部に到達しようとすることではなく、クラスメンバー名しか参照できないことですafter宣言されています。

(もちろん)前方宣言はcという名前のメンバーを導入しないため、そのような名前を参照するのは不適切です。


誤解を招く診断...

コードが送られたときにgccclangの両方によって発行される診断はやや誤解を招く恐れがありますが、正直なところ、バグレポートが適切であると感じています。

foo.cpp:3:8: error: incomplete type 'A' named in nested name specifier


arenested-name-specifierで不完全な型に名前を付けることができますが、前述のとおりです。まだ宣言されていないメンバーを参照することはできません。

不正な形式:

class X {
  static int a[X::x];        // ill-formed, `X::x` has not yet been declared
  static int const x = 123;
};

legal:

class X {
  int const x = 123;
  int a[X::x]; // legal, `X` is incomplete (since we are still defining it)
               //        but we can still refer to a _declared_ member of it
};
38