C ++类的语法定义为
class-key identifier *[opt]* base-clause *[opt]*
(斜体是我的)
这对我来说意味着类名是选项,我们可以在C ++中使用未命名的类。
那么,以下结构良好吗?
struct X{
struct{
int x;
int y;
};
};
int main(){}
VS:错误C2467:非法声明 匿名'struct'
Comeau online:错误:声明确实如此 不要宣布任何事情 结构{
GCC(ideone):编译正确
有什么想法吗?
答案 0 :(得分:7)
不,它不是很好。您无法单独从这些语法语句中派生语言语法。标准文本中给出的额外要求也必须予以考虑。在这种情况下,这将是
7声明
...
3 在简单声明中,可选的 init-declarator-list 可以是 仅在声明类时省略 (第9条)或列举(7.2),即 是,当 decl-specifier-seq 时 包含类说明符,an elaboratedtype-specifier with a class-key (9.1)或枚举说明符。 在这些情况下,每当一个 class-specifier 或 enum-specifier 是 出现在 decl-specifier-seq 中 这些说明符中的标识符是 在被宣布的名字中 声明(作为类名, enum-names 或枚举器,具体取决于 关于语法)。 在这种情况下,和 除了声明 未命名的位域(9.6),. decl-specifier-seq 应引入一个 或更多名称加入该计划,或 应重新声明由a引入的名称 先前的声明。
最后一句是在这种情况下重要的一句话
“可选”部分仅用于允许声明,如
struct { int x; } s;
typedef struct { int x, y; } Point;
第一个声明类型没有该类型的链接和变量s
的类型。请注意,没有链接的类型不能用于声明具有链接的变量,这意味着此类声明不能在命名空间范围中使用。
你的例子形象不对,但这是合法的
struct X {
struct {
int x;
int y;
} point;
};
此外,无名类语法用于声明匿名联合(虽然我对7/3没有提到匿名联合的事实感到有点困惑)。
答案 1 :(得分:0)
该代码实际上在MSVC中有效,您必须以受限模式编译。
虽然我很可能永远不会使用它们,但它们确实允许一些有趣的用法,例如:
X obj;
obj.x=1;
obj.y=2;
例如,它们用于LARGE_INTEGER
类,而只是union
。这样,当您真正想要的一个成员可以拆分成更小的部分时,您可以避免使用子对象。
LARGE_INTEGER
声明作为一个直观的例子:
#if defined(MIDL_PASS)
typedef struct _LARGE_INTEGER {
#else // MIDL_PASS
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
};
struct {
DWORD LowPart;
LONG HighPart;
} u;
#endif //MIDL_PASS
LONGLONG QuadPart;
} LARGE_INTEGER;
据我所知,这不是有效的标准C ++,它只允许作为gcc和msvc中的扩展。