“匿名结构”是标准吗? 而且,真的,他们是什么?
MSDN认为匿名结构在C ++中是非标准的:
Microsoft C扩展允许您在不指定名称的情况下在另一个结构中声明结构变量。 这些嵌套结构称为匿名结构。 C ++不允许匿名结构。
您可以访问匿名结构的成员,就好像它们是包含结构中的成员一样。
@ K-ballo对此表示赞同。
我被告知这个特性不一定与创建一个未命名的结构相同,但我无法看到标准措辞方面的区别。
C ++ 11说:
[C++11: 9/1]
:[..]一个class-specifier,它的class-head省略了class-head-name,定义了一个未命名的类。
并为缺少名称的类型定义提供了完整的语法结构。
C ++ 03缺少这种明确的措辞,但同样表明类型定义中的identifier
是可选的,并且引用9.4.2/5
和3.5/4
“未命名类”。
所有的标准文本都是指创建一个“无名结构”:
struct {
int hi;
int bye;
};
只是一个很好的友好类型,没有可访问的名称。
以一种标准的方式,它可以被实例化为这样的成员:
struct Foo {
struct {
int hi;
int bye;
} bar;
};
int main()
{
Foo f;
f.bar.hi = 3;
}
但是一个“匿名结构”是微妙不同的 - 它是“未命名结构”的组合,以及你在父对象中魔法地将其成员从其中取出的事实:
struct Foo {
struct {
int hi;
int bye;
}; // <--- no member name!
};
int main()
{
Foo f;
f.hi = 3;
}
与直觉相反†,这不仅仅创建了一个与Foo
嵌套的未命名结构,而且还自动为您提供了一个“匿名成员”,使成员可以在父对象中进行访问。
这是非标准的功能。 GCC支持它,Visual C ++也支持它。 Windows API头默认使用此功能,但您可以在包含Windows头文件之前添加#define NONAMELESSUNION
来指定您不需要此功能。
与做类似事情的“匿名工会”的标准功能相比:
struct Foo {
union {
int hi;
int bye;
}; // <--- no member name!
};
int main()
{
Foo f;
f.hi = 3;
}
†看来,尽管术语“未命名”是指类型(即“类”或“结构”)本身,但术语“匿名”指的是实际实例化的成员(使用较旧的含义“结构“这更接近”某个struct
类型的对象“)。 这可能是你最初混淆的根源。
微软称匿名结构的东西不是标准的。 未命名的结构只是一个没有名字的普通结构。 除非你还定义了一个这种类型的对象,否则你可以用一个来做很多事情:
struct {
int i;
double d;
} my_object;
my_object.d = 2.3;
匿名工会是标准的一部分,它们具有您通过阅读微软对其匿名结构的描述所期望的行为:
union {
int i;
double d;
};
d = 2.3;
标准谈论匿名工会:[9.5] / 5
表单的联合
union { member-specification } ;
被称为匿名联盟; 它定义了一个未命名类型的未命名对象。 匿名联合的成员规范只能定义非静态数据成员。 [注意:嵌套类型和函数不能在匿名联合中声明。 - 注意]匿名工会成员的姓名应与匿名工会申报范围内任何其他实体的姓名不同。 为了名称查找的目的,在匿名联合定义之后,匿名联合的成员被认为是在声明匿名联合的范围内定义的。 [例如:
void f() {
union { int a; const char* p; };
a = 1;
p = "Jennifer";
}
在这里,a和p与普通(非成员)变量一样使用,但由于它们是工会成员,因此它们具有相同的地址。 - 例子]
微软谈到的匿名结构是针对unions
这个功能,但是适用于structs
。 不仅仅是一个未命名的定义,重要的是要注意,匿名联合/结构的mebers被认为是在声明了匿名联合/结构的范围内定义的。
据我所知,标准中未命名的结构没有这种行为。 请注意,在引用的示例中,您可以实现其他方式无法实现的功能,例如共享栈中变量的存储空间,而匿名结构并不会为表格带来新的功能。
链接地址: http://www.djcxy.com/p/90827.html上一篇: Are "anonymous structs" standard? And, really, what *are* they?