两级嵌套 c++ 类适用于 GCC,但使用 Clang 失败
Posted
技术标签:
【中文标题】两级嵌套 c++ 类适用于 GCC,但使用 Clang 失败【英文标题】:Two level nested c++ class works with GCC but fails with 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)
【问题讨论】:
【参考方案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-name 的 nested-name-specifier 不应以 decltype-specifier.
在您的情况下,class-specifier struct A::B
确实 不 出现在命名空间的范围内,而是出现在类的范围内(尝试更改 struct Base
进入namespace Base
,你会看到 Clang 接受它)。
因此,解决此问题的正确方法是在命名空间范围内定义类,而不是在 Base
内:
// ...
struct Base::A::B
;
【讨论】:
以上是关于两级嵌套 c++ 类适用于 GCC,但使用 Clang 失败的主要内容,如果未能解决你的问题,请参考以下文章
focus-within 适用于 Android 浏览器,但不适用于 iOS