3

宣言されているクラスの外部で内部クラスを定義する際に問題があります。

struct Base {
    struct A {
        struct B;
    };
    struct A::B {
    };
};

コンパイルして GCC で動作しますが、Clang では次のエラーで失敗します。

innerclass.cpp:6:12: error: non-friend class member 'B' cannot have a qualified name
    struct A::B {
           ~~~^

最も外側のクラス Base が省略されている場合、コードは Clang で機能します。

このように内部クラスを定義することは違法ですか? もしそうなら、それはどのように行われるべきですか?

プラットフォーム:
OS X 10.8.3
XCode 4.6.2
Clang Apple LLVM バージョン 4.2 (clang-425.0.24) (LLVM 3.2svn ベース)
GCC gcc バージョン 4.2.1 (Apple Inc. ビルド 5658 ベース) (LLVM ビルド 2336.11. 00)

4

1 に答える 1

5

残念ながら、GCC は寛大です。C++11 標準のパラグラフ 9/1 では、class-head-nameは次のように指定されています。

ネストされた名前指定子 (opt) クラス名

つまり、修飾名をクラスの名前として使用できます。また、パラグラフ 9/11 の最初の部分は次のように指定しています。

class-head-namenested-name-specifierが含まれている場合、class - specifierは、nested-name-specifier が参照するクラスまたは名前空間で以前に直接宣言されたクラスを参照するものとします[ ...]

Bそして、実際に class内で classを宣言しAました。ただし、同じ段落の 2 番目の部分は次のように追加します。

[...] そしてクラス指定子 は、前の宣言を囲む名前空間に現れるものとします。そのような場合、定義のclass-head-nameのnested-name-specifierはdecltype-specifierで始まってはなりません 。

あなたの場合、クラス指定子 struct A::B { }は名前空間のスコープではなく、クラスのスコープに表示されます (に変更struct Basenamespace Baseてみると、Clang がそれを受け入れることがわかります)。

したがって、これを修正する正しい方法は、内部ではなく名前空間スコープでクラスを定義することですBase

// ...

struct Base::A::B
{
};
于 2013-05-26T12:05:56.423 に答える