某些C ++编译器允许匿名联合和结构作为标准C ++的扩展。这有点语法糖,偶尔会非常有用。
阻止此成为标准一部分的理由是什么?是否存在技术障碍?一个哲学的?或者仅仅是不足以证明它的合理性?
以下是我所谈论的一个示例:
struct vector3 {
union {
struct {
float x;
float y;
float z;
};
float v[3];
};
};
我的编译器会接受这个,但它会警告"nameless struct/union" is a non-standard extension to C++。
答案 0 :(得分:41)
正如其他人所指出的那样,标准C ++允许使用匿名联合,但匿名结构不允许。
原因是C支持匿名联合但不支持匿名结构*,因此C ++支持前者的兼容性而不支持后者,因为兼容性不需要它。
此外,C ++中的匿名结构没有多大用处。您演示的用法是,包含三个浮点数的结构可以由.v[i]
或.x
,.y
和.z
引用,我相信结果是未定义的C ++中的行为。 C ++不允许你写一个联盟的一个成员,比如说.v[1]
,然后从另一个成员那里读,比如说.y
。尽管执行此操作的代码并不罕见,但实际上并未明确定义。
C ++用户定义类型的工具提供了替代解决方案。例如:
struct vector3 {
float v[3];
float &operator[] (int i) { return v[i]; }
float &x() { return v[0]; }
float &y() { return v[1]; }
float &z() { return v[2]; }
};
* C11显然添加了匿名结构,因此未来的C ++修订版可能会添加它们。
答案 1 :(得分:17)
我会说,您只需使用vector3
union
声明
union vector3 {
struct { float x, y, z; } ;
float v[3] ;
} ;
当然,anonymous structures was an MSVC extension。但ISO C11现在允许它,gcc allows it,Apple的llvm编译器也是如此。
为什么在C11而不是C ++ 11?我不确定,但实际上大多数(gcc ++,MSVC ++和Apple的C ++编译器)C ++编译器都支持它们。
答案 2 :(得分:7)
不确定你的意思。 C ++规范的第9.5节,第2节:
表格
的联合union { member-specification } ;
被称为匿名联盟;它定义了一个未命名类型的未命名对象。
你也可以做这样的事情:
void foo()
{
typedef
struct { // unnamed, is that what you mean by anonymous?
int a;
char b;
} MyStructType; // this is more of a "C" style, but valid C++ nonetheless
struct { // an anonymous struct, not even typedef'd
double x;
double y;
} point = { 1.0, 3.4 };
}
并不总是非常有用......虽然有时在令人讨厌的宏定义中很有用。
答案 3 :(得分:1)
工会可以是匿名的;见标准,9.5第2段。
您认为匿名结构或类的目的是什么?在推测为什么某些东西不在标准中之前,我想知道为什么它应该是,并且我没有看到用于匿名结构。
答案 4 :(得分:1)
您的代码
union {
struct {
float x;
float y;
float z;
};
float v[3];
};
就像
union Foo {
int;
float v[3];
};
肯定无效(在C99及之前)。
原因是可能来简化解析(在C中),因为在这种情况下你只需要检查struct / union主体是否只有“声明符语句”,如
Type field;
尽管如此,gcc and "other compilers"支持未命名的字段作为扩展名。
编辑:现在,C11(§6.7.2.1/ 13)正式支持匿名结构。
答案 5 :(得分:1)
基于编辑,评论和这篇MSDN文章:Anonymous Structures,我会冒险猜测 - 它与封装的概念很不一致。我不希望类的成员混淆我的类命名空间,而不仅仅是添加一个成员。此外,对匿名结构的更改可能会在未经许可的情况下影响我的课程。