【问题标题】:Two level nested c++ class works with GCC but fails with Clang两级嵌套 c++ 类适用于 GCC,但使用 Clang 失败
【发布时间】:2013-05-26 12:01:01
【问题描述】:

在声明它的类之外定义内部类时遇到问题。

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)

【问题讨论】:

    标签: c++ macos clang nested-class


    【解决方案1】:

    恐怕 GCC 会放任自流。 C++11 标准的第 9/1 段指定 class-head-name 是:

    nested-name-specifier(opt) 类名

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

    如果 class-head-name 包含 nested-name-specifier,则 class-specifier 应指那是 之前直接在 nested-name-specifier 引用的类或命名空间中声明,[...]

    你确实在类A 中声明了类B。但是,同一段的第二部分添加了:

    [...] 和 类说明符 应出现在包含先前声明的命名空间中。在这种情况下,定义的 class-head-namenested-name-specifier 不应以 decltype-specifier.

    在您的情况下,class-specifier struct A::B { } 确实 出现在命名空间的范围内,而是出现在类的范围内(尝试更改 struct Base进入namespace Base,你会看到 Clang 接受它)。

    因此,解决此问题的正确方法是在命名空间范围内定义类,而不是在 Base 内:

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

    【讨论】:

      猜你喜欢
      • 2014-07-08
      • 1970-01-01
      • 1970-01-01
      • 2021-09-22
      • 2022-11-26
      • 2018-03-15
      • 1970-01-01
      • 2014-11-26
      • 1970-01-01
      相关资源
      最近更新 更多