MSDN 认为匿名结构在C++中是非标准的:
Microsoft C扩展允许您在另一个结构中声明结构变量而不为其指定名称.这些嵌套结构称为匿名结构.C++不允许匿名结构.
您可以访问匿名结构的成员,就好像它们是包含结构中的成员一样.
我被告知这个功能不一定只是创建一个未命名的结构,但我不能看到标准措辞的区别.
C++ 11说:
[C++11: 9/1]
:[..]一个类说明符,其类头省略了class-head-name,定义了一个未命名的类.
并为缺少名称的类型定义提供完整的语法结构.
C++ 03缺少这种明确的措辞,但同样表明identifier
类型定义中的类型是可选的,并在9.4.2/5
和中引用了"未命名的类" 3.5/4
.
Lig*_*ica 57
所有标准文本都指创建一个"未命名的结构":
struct {
int hi;
int bye;
};
Run Code Online (Sandbox Code Playgroud)
只是一个友好的友好类型,没有可访问的名称.
以标准方式,它可以实例化为这样的成员:
struct Foo {
struct {
int hi;
int bye;
} bar;
};
int main()
{
Foo f;
f.bar.hi = 3;
}
Run Code Online (Sandbox Code Playgroud)
但是"匿名结构"略有不同 - 它是"未命名的结构"的组合,以及您在父对象中神奇地从其中获取成员的事实:
struct Foo {
struct {
int hi;
int bye;
}; // <--- no member name!
};
int main()
{
Foo f;
f.hi = 3;
}
Run Code Online (Sandbox Code Playgroud)
与直觉†相反,这不只是创建一个嵌套的未命名结构Foo
,而且还会自动为您提供各种"匿名成员",使成员可以在父对象中访问.
这个功能是非标准的.GCC 确实支持它,Visual C++也是如此.Windows API标头默认使用此功能,但您可以#define NONAMELESSUNION
在包含Windows标头文件之前通过添加来指定您不希望它.
与"匿名工会" 的标准功能相比,它们执行类似的操作:
struct Foo {
union {
int hi;
int bye;
}; // <--- no member name!
};
int main()
{
Foo f;
f.hi = 3;
}
Run Code Online (Sandbox Code Playgroud)
†看起来虽然术语"未命名"指的是类型(即"类"或"结构")本身,但术语"匿名"指的是实际的实例化成员(使用"结构"的旧含义) "那更接近"某种struct
类型的对象").这可能是您最初混淆的根源.
Pet*_*ker 12
微软称之为匿名结构的东西不是标准的.未命名的结构只是一个没有名称的普通结构.除非您还定义了该类型的对象,否则您无法使用其中一个:
struct {
int i;
double d;
} my_object;
my_object.d = 2.3;
Run Code Online (Sandbox Code Playgroud)
匿名工会是标准的一部分,它们具有您期望阅读Microsoft对其匿名结构的描述的行为:
union {
int i;
double d;
};
d = 2.3;
Run Code Online (Sandbox Code Playgroud)
该标准谈到了匿名工会:[9.5]/5
形式的联合
Run Code Online (Sandbox Code Playgroud)union { member-specification } ;
被称为匿名联盟; 它定义了一个未命名类型的未命名对象.匿名联合的成员规范只应定义非静态数据成员.[注意:嵌套类型和函数不能在匿名联合中声明.-end note]匿名工会成员的名称应与宣布匿名工会的范围内的任何其他实体的名称不同.出于名称查找的目的,在匿名联合定义之后,匿名联合的成员被认为已在声明匿名联合的范围中定义.[例如:
Run Code Online (Sandbox Code Playgroud)void f() { union { int a; const char* p; }; a = 1; p = "Jennifer"; }
这里a和p像普通(非成员)变量一样使用,但由于它们是联合成员,因此它们具有相同的地址. - 末端的例子]
该匿名结构是微软谈论是此功能unions
,但应用到structs
.不仅仅是一个未命名的定义,重要的是要注意匿名union/struct的标准被认为是在声明匿名union/struct的范围内定义的.
据我所知,标准中没有未命名结构的行为.请注意,在引用的示例中,您可以实现无法实现的功能,例如共享堆栈中变量的存储,而匿名结构不会给表带来任何新内容.