我很确定这是可能的,因为我很确定我已经看到它完成了.我认为这很棒,但我很乐意接受"这是一个可怕的想法,因为____"的答案.
假设我们有一个基本结构.
struct vertex { float x, y, z; };
现在,我想在这些变量上实现别名.
vertex pos; vertex col; vertex arr; pos.x = 0.0f; pos.y = 0.5f; pos.z = 1.0f; col.r = 0.0f; col.g = 0.5f; col.b = 1.0f; arr[0] = 0.0f; arr[1] = 0.5f; arr[2] = 1.0f;
理想情况下,第三种语法与数组无法区分.也就是说,如果我arr
作为参考参数发送给期望其将存储数据的浮点数组的函数(例如许多OpenGL glGet
函数),它将正常工作.
你怎么看?可能?可能但很愚蠢?
我要做的是制作访问者:
struct Vertex { float& r() { return values[0]; } float& g() { return values[1]; } float& b() { return values[2]; } float& x() { return values[0]; } float& y() { return values[1]; } float& z() { return values[2]; } float operator [] (unsigned i) const { return this->values_[i]; } float& operator [] (unsigned i) { return this->values_[i]; } operator float*() const { return this->values_; } private: float[3] values_; }
联合中的无名嵌套结构不是标准的C++.但是,这应该有效:
struct Vertex { private: typedef float Vertex::* const vert[3]; static const vert v; public: typedef size_t size_type; float x, y, z; const float& operator[](size_type i) const { return this->*v[i]; } float& operator[](size_type i) { return this->*v[i]; } }; const Vertex::vert Vertex::v = {&Vertex::x, &Vertex::y, &Vertex::z};
编辑:更多信息.该struct使用3个指针到数据成员的数组来访问重载[]运算符中的数据.
行"typedef float Vertex ::*const vert"表示vert是指向Vertex结构的float成员的指针.[3]意味着它是其中3个的数组.在重载的operator []中,对此数组进行索引,并取消引用指向数据的成员并返回值.
此外,无论打包问题如何,此方法都可以正常工作 - 编译器可以自由填充顶点结构,但它仍然可以正常工作.如果浮动包装不同,匿名联合将遇到问题.
使用工会?
union vertex { struct { float x, y, z; }; struct { float r, g, b; }; float arr[3]; };
我不推荐它 - 它会导致混乱.
补充:
正如Adrian在他的回答中所指出的那样,ISO C++不支持这种与匿名结构成员的联合.它适用于GNU G ++(当你打开' -Wall -ansi -pedantic
' 时会抱怨不支持).它让人想起预先标准化的C天(K&R 1st Edn之前),当结构元素名称必须在所有结构中都是唯一的时候,你可以使用缩小的符号来获得结构中的偏移量,你可以使用其他结构类型的成员名称 - 一种无政府状态.当我开始使用C(很久以前,但后K&R1)时,这已经是历史用法了.
使用匿名联合成员(对于这两种结构)显示的符号由C11(ISO/IEC 9899:2011)支持,但不受早期版本的C标准支持.ISO/IEC 14882:2011(C++ 11)第9.5节规定了匿名联合,但GNU g++
(4.9.1)不接受显示的代码-pedantic
,标识" warning: ISO C++ prohibits anonymous structs [-Wpedantic]
".
由于这个想法会导致混乱,我并不特别担心它不标准; 我不会使用这个机制来完成这个任务(我会对在联合中使用匿名结构感到谨慎,即使它是有益的).
提出了一个问题:
三个(xyz,rgb和数组)不一定对齐.
它是一个有三个要素的联盟; 这三个元素从同一地址开始.前两个是包含3个浮点值的结构.没有继承,也没有虚拟函数来提供不同的布局等.结构将以三个连续的元素排列(实际上,即使标准允许填充).该数组也从相同的地址开始,并且在结构中经历"无填充",元素与两个结构重叠.我真的没有看到会出现问题.