7

私の理解では、この例のように、指定子が使用されたfriend場合、宣言はクラスの前方宣言としても機能する可能性があります。class

class A
{
    friend class B;
    B* b;
};

class B {};

int main() {}

ただし、g ++(4.6.3および4.7.0)では次のエラーが発生します(g ++-4.7は拡張フレンド宣言をサポートしている必要があります)。これは前方宣言なしで予期されます。

main.cpp:6:2:エラー:「B」はタイプに名前を付けていません

friend class B;が前方宣言として機能するという私の期待を確認するために、私はこの答えこの答えを見つけましたが、どちらも決定的ではなかった(または少なくともそれらから多くを結論付けることができなかった)ので、c++を調べようとしました11標準であり、この例が見つかりました:

class X2 {
    friend Ct; // OK: class C is a friend
    friend D; // error: no type-name D in scope
    friend class D; // OK: elaborated-type-specifier declares new class
}

3番目の宣言を読んだことに基づいて、私は新しいクラスを宣言する精巧な型指定子friend class Bである必要があります。

私は公式の標準的な言い回しを理解し始めたばかりなので、何かが欠けているに違いありません。私は何を誤解していますか?

4

2 に答える 2

6

11.3 パラグラフ 11 を見てください。

フレンド クラス宣言の場合、前の宣言がない場合、指定されたクラスは最内囲みの非クラス スコープに属しますが、後で参照される場合、一致する宣言が最も内側にある非クラス スコープ。

例:

class X;
void a();
void f() {
  class Y;
  extern void b();
  class A {
  friend class X;  // OK, but X is a local class, not ::X
  friend class Y;  // OK
  friend class Z;  // OK, introduces local class Z.
  friend void a(); // error, ::a is not considered
  friend void b(); // OK
  friend void c(); // error
  };
  X *px;           // OK, but ::X is found
  Z *pz;           // error, no Z is found
}
于 2013-01-01T23:06:40.410 に答える
5

あなたのfriend class B;宣言前方宣言として機能しますが、一致する宣言が提供されるまで、そのような宣言は名前検索によって見つかりません。

[class.friend]/11 :

フレンド宣言がローカル クラス (9.8) に表示され、指定された名前が非修飾名である場合、最内囲みの非クラス スコープの外側にあるスコープを考慮せずに、前の宣言が検索されます。フレンド関数宣言の場合、前の宣言がない場合、プログラムは不正な形式です。フレンド クラス宣言の場合、前の宣言がない場合、指定されたクラスは最内囲みの非クラス スコープに属しますが、後で参照される場合、一致する宣言が最も内側にある非クラス スコープ。

于 2013-01-01T23:05:51.703 に答える