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. build 5658)(LLVM build 2336.11。 00)

4

1 回答 1

5

恐怕海湾合作委员会会放任自流。C++11 标准的第 9/1 段指定类头名称是:

嵌套名称说明符(选择)类名

这意味着限定名称可以用作类的名称。此外,第 9/11 段的第一部分规定:

如果一个类头名称包含一个嵌套名称说明符,则该类说明符应引用先前直接在嵌套名称说明符所指的类或命名空间中声明的类,[...]

而且您确实确实在 class 中声明了Bclass A。但是,同一段的第二部分补充说:

[...] 并且类说明符 应出现在包含先前声明的命名空间中。在这种情况下,定义的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 回答