1. ホーム
  2. c++

[解決済み] ネストされた名前指定子における不完全な型

2022-02-28 03:42:53

質問

以下のようにネストした名前指定子で不完全な型を使おうとしました。

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)を適用する。 そのクラス、名前空間、またはそれを示す入れ子の名前指定子 列挙

では、その動作は実装依存なのでしょうか?

解決方法は?

はじめに

規格の中には、あなたのコードが不正確であることを暗に示唆する箇所がいくつかありますが、以下の引用文がそれを物語っています。

<ブロッククオート

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

クラスのメンバを宣言した時点から、そのクラスのスコープでメンバ名を調べることができるようになります。

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

この前方宣言では、(もちろん) c そのような名前を参照するのは不正な形式です。


誤解を招くような診断...

両者が発行する診断書 gcc クラング というのは誤解を招きやすいので、正直なところ、バグレポートが必要だと感じています。

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


私たち で不完全な型を指定することができます。 ネストされた名前指定子 しかし、前述のように、まだ宣言されていないメンバーを参照することはできません。

不正な形式です。

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

を合法とする。

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
};