联盟黑客需要

Art*_*ium 6 c c++

我有一个表示顶点的结构.它有x,y和z字段以及其他几个字段.最近我得出结论,对于某些功能,我需要以数组的形式访问顶点的坐标.我不想用临时变量"污染"代码或者将所有看起来像这样的地方v.y改为v.coord[1]不好或不优雅.所以我考虑使用工会.这样的事情应该有效:

struct {
  float x,y,z;
} Point;

struct {
    union {
        float coord[3];
        Point p;
    };
} Vertex;
Run Code Online (Sandbox Code Playgroud)

这很好,但并不完美.点类没有意义.我希望能够通过键入v.y(而不是v.p.y)来访问y坐标.
你能建议一个黑客来解决这个问题(或者告诉我这是不可能的)?

Jam*_*lis 14

一个好的C++方法是使用返回元素引用的命名访问器:

class Point {
public:
    float& operator[](int x)       { assert(x <= 2); return coords_[x]; }
    float  operator[](int x) const { assert(x <= 2); return coords_[x]; }

    float& X()       { return coords_[0]; }
    float  X() const { return coords_[0]; }

    float& Y()       { return coords_[1]; }
    float  Y() const { return coords_[1]; }

    float& Z()       { return coords_[2]; }
    float  Z() const { return coords_[2]; }
private:
    float coords_[3];
};
Run Code Online (Sandbox Code Playgroud)

使用这种方法,给定a Point p;,您可以使用p[0]p.X()访问内部coords_数组的初始元素.

  • +1.任何体面的编译器设置为优化都会将这些内置到位,因此它将与任何联合黑客一样高效. (2认同)
  • 如果你要断言x <= 2,那么添加0 <= x也会很好. (2认同)

Raf*_*fid 12

好的,这应该对你有用

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

这段代码的作用是将数组与结构联合起来,因此它们共享相同的内存.由于结构不包含名称,因此可以在没有名称的情况下访问它,就像union本身一样.

  • 不幸的是,它不是标准的C++. (8认同)
  • 它在技术上违反了联合存储规则.您只能从您上次写入的联合元素中读取.所以,如果你写'coord [1]`,你只能从`coord`数组读取,不能读取`x`,`y`或`z`,如果你写'z`,你只能读取`x`,`y`和`z`元素,但不能读取`coord`数组.结构的元素之间也可能存在填充(这是非常不可能的,但它是可能的).说这是无效的C++是一个迂腐但有效的投诉. (5认同)
  • AFAIK VC++说"使用了非标准扩展",在GCC中你可以用一些标志打开这个功能.然而,C99/C++ 98,03,0x标准只有匿名联合,而不是匿名结构. (3认同)
  • @All:相关:http://stackoverflow.com/questions/1972003/how-to-use-anonymous-structs-unions-in-c和http://stackoverflow.com/questions/2253878/why-does-c -disallow命名的 - 结构 - 和 - 工会 (2认同)