3

クラスのメンバーを転送宣言するときは、実行するかclass Bar; Bar* m_bar、より短いものを使用できますclass Bar* m_bar。しかし、名前解決の動作は異なるようです。

たとえば、これは完全にコンパイルされます。

struct Foo {
  Foo();
  struct Bar;
  Bar* m_bar;
  struct Bar {
      int m_baz;
  };
};

Foo::Foo(){
    m_bar = new Foo::Bar;
}

これはそうではありませんが、コンパイラはのタイプが単なるものでm_barはないと考えているためです。Foo::BarBar

struct Foo {
  Foo();
  struct Bar* m_bar;
  struct Bar {
      int m_baz;
  };
};

Foo::Foo(){
    m_bar = new Foo::Bar;
}

私の質問は実際の問題よりも好奇心からです(そして前方宣言とネストされたクラスはC ++では厄介な問題であることを知っています)が、なぜコンパイラは2番目のバージョンをグローバル名として解釈するのですか?

4

1 に答える 1

2

仕様では、3.3.2p6bullet2でこれを示しています(実際には、宣言された名前がどのスコープに追加されるかを示しています。正しく覚えていれば、クラスがその名前空間のメンバーであるという明示的なルールはありません)。

これは重要なC互換機能だと思います。この方法でなかった場合、クラスはCではグローバルになりますが、C++ではクラスメンバーになります。

于 2013-03-01T20:42:09.283 に答える