2

例は次のとおりです。

struct A
{
    A(const int a ):b(a)
    {
    }

    int b;
};

struct B
{
    B() : a(5)
    {
    }

    static void A()
    {
    }

    A a;
};

int main()
{
    B::A();
}

コンパイラエラーは次のとおりです。

a9.cpp:19: error: ‘A’ does not name a type
a9.cpp: In constructor ‘B::B()’:
a9.cpp:24: error: class ‘B’ does not have any field named ‘a’

Fedora 9 で gcc 4.3.0 を使用しています。

誰かがコンパイラが不平を言っている理由を説明できますか? 可能であれば、標準からの参照とともに。

ありがとう

4

1 に答える 1

8

これは機能します:

struct B {
    B() : a(5) { }

    static void A() { }

    ::A a;
};

Aでメンバー名として使用したので、そのメンバーの定義は外部名前空間からの型をBシャドウします。Aを使用::すると、その名前空間に到達できます。

この動作は、(ドラフト)標準で次のように指定されています。

3.3.7(1)「名前は、ネストされた宣言型領域で同じ名前を明示的に宣言することで非表示にできます」(の定義はstruct B、も定義されている名前空間にネストされていますstruct A)。

さらに明確にするために、第3章「基本概念」の概要を注意深く読んでください。特に、このセクションでは次のように指定しています

3(7)次の場合、2つの名前は同じです

  • それらは同じ文字シーケンスで構成される識別子です。また
  • これらは、同じ演算子で形成されたオーバーロードされた演算子関数の名前です。また
  • これらは、同じタイプで形成されたユーザー定義の変換関数の名前です。

この最後の定義はタイプとクラスメンバーを区別しないため、名前の非表示(シャドウイング)ルール3.3.7(1)が適用されることに注意してください。

于 2010-11-09T14:16:51.880 に答える