为什么C++不允许使用匿名结构?

Adr*_*thy 87 c++ struct unions

一些C++编译器允许匿名联合和结构作为标准C++的扩展.这有点语法糖,偶尔会非常有帮助.

阻止它成为标准一部分的理由是什么?是否存在技术障碍?一个哲学的?或者仅仅是不足以证明它的合理性?

这是我正在谈论的样本:

struct vector3 {
  union {
    struct {
      float x;
      float y;
      float z;
    };
    float v[3];
  };
};
Run Code Online (Sandbox Code Playgroud)

我的编译器会接受这个,但它警告"无名结构/联合"是C++的非标准扩展.

bam*_*s53 45

正如其他人所指出的那样,标准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]; }
};
Run Code Online (Sandbox Code Playgroud)

*C11显然添加了匿名结构,因此未来对C++的修订可能会添加它们.

  • @underscore_d:是的,如果类型是具有共同初始序列的标准布局.但是,结构永远不能以这种方式使用*array*进行别名,因为C++的"公共初始序列"规则规定公共初始序列只能在*结构*之间.没有提到数组,因此它们不能像这样别名. (5认同)
  • +1:我的例子依赖于C++中未定义的行为 - 当我写这个问题时我不知道这件事. (2认同)
  • "C++不允许你写一个union [...]的一个成员,然后从另一个成员读取" - **除非**表示成员是标准布局对象并且共享一个_common初始序列_他们自己的成员,你正在所述公共初始序列中写/读_their_成员._is_允许(即定义). (2认同)

bob*_*obo 20

我会说,你可以vector3通过使用一个来清理你的声明union

union vector3 {
  struct { float x, y, z; } ;
  float v[3] ;
} ;
Run Code Online (Sandbox Code Playgroud)

当然,匿名结构 MSVC扩展.但是ISO C11现在允许它,gcc允许它,Apple的llvm编译器也是如此.

为什么在C11而不是C++ 11?我不确定,但实际上大多数(gcc ++,MSVC++和Apple的C++编译器)C++编译器都支持它们.

  • 谢谢。我从来没有像一个struct或class那样使用过工会。 (2认同)

Dan*_*Dan 6

不明白你的意思.C++规范的第9.5节,第2节:

形式的联合

union { member-specification } ;
Run Code Online (Sandbox Code Playgroud)

被称为匿名联盟; 它定义了一个未命名类型的未命名对象.

你也可以做这样的事情:

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 };
}
Run Code Online (Sandbox Code Playgroud)

并不总是非常有用...虽然有时在令人讨厌的宏定义中有用.

  • -1因为它说它定义了一个匿名结构.请参阅上面关于问题的评论 - 您正在定义一个未命名的结构,而不是匿名结构. (11认同)