在父 class 中定义子 class 的子结构
Defining sub-structure of sub-class inside parent class
考虑以下代码片段:
class MyClass
{
private:
struct PrivateClass
{
struct SubStruct;
};
public:
struct PrivateClass::SubStruct {};
private:
PrivateClass::SubStruct member;
};
MSVC 和 gcc 编译这段代码没有任何错误。但是,clang 会产生以下错误:
<source>:10:26: error: non-friend class member 'SubStruct' cannot have a qualified name
struct PrivateClass::SubStruct {};
那么,谁是对的?这是 clang 错误吗?
根据 C++ 17 标准中的 [class]/11
:
If a class-head-name contains a nested-name-specifier, the
class-specifier shall refer to a class that was previously declared
directly in the class or namespace to which the nested-name-specifier
refers, or in an element of the inline namespace set (10.3.1) of that
namespace (i.e., not merely inherited or introduced by a
using-declaration), and the class-specifier shall appear in a
namespace enclosing the previous declaration. In such cases, the
nested-name-specifier of the class-head-name of the definition shall
not begin with a decltype-specifier.
看来 clang 编译器是对的。
标准(最新草案)说:
[class.nest]
If class X is defined in a namespace scope, a nested class Y may be declared in class X and later defined in the definition of class X or be later defined in a namespace scope enclosing the definition of class X.
在此示例中,在 class PrivateClass
中声明的 class SubStruct
既不在稍后的 PrivateClass
中定义,也不在稍后的 a 中定义命名空间范围(而是稍后在外部 MyClass
的 class 范围内)。 PrivateClass
本身也不在命名空间范围内定义。
除非有另一条规则允许这样做,否则至少不会明确允许示例中的子嵌套 class 的定义。 Clang 似乎是正确的。
考虑以下代码片段:
class MyClass
{
private:
struct PrivateClass
{
struct SubStruct;
};
public:
struct PrivateClass::SubStruct {};
private:
PrivateClass::SubStruct member;
};
MSVC 和 gcc 编译这段代码没有任何错误。但是,clang 会产生以下错误:
<source>:10:26: error: non-friend class member 'SubStruct' cannot have a qualified name
struct PrivateClass::SubStruct {};
那么,谁是对的?这是 clang 错误吗?
根据 C++ 17 标准中的 [class]/11
:
If a class-head-name contains a nested-name-specifier, the class-specifier shall refer to a class that was previously declared directly in the class or namespace to which the nested-name-specifier refers, or in an element of the inline namespace set (10.3.1) of that namespace (i.e., not merely inherited or introduced by a using-declaration), and the class-specifier shall appear in a namespace enclosing the previous declaration. In such cases, the nested-name-specifier of the class-head-name of the definition shall not begin with a decltype-specifier.
看来 clang 编译器是对的。
标准(最新草案)说:
[class.nest]
If class X is defined in a namespace scope, a nested class Y may be declared in class X and later defined in the definition of class X or be later defined in a namespace scope enclosing the definition of class X.
在此示例中,在 class PrivateClass
中声明的 class SubStruct
既不在稍后的 PrivateClass
中定义,也不在稍后的 a 中定义命名空间范围(而是稍后在外部 MyClass
的 class 范围内)。 PrivateClass
本身也不在命名空间范围内定义。
除非有另一条规则允许这样做,否则至少不会明确允许示例中的子嵌套 class 的定义。 Clang 似乎是正确的。