如何从3维向量v3联合体中提取XZ坐标作为v2二维向量
解决方案
完全可以实现该需求,你当前写法的核心问题在于:v2 要求两个float值内存连续,而v3中的x和z中间间隔了y的4字节内存,无法直接通过嵌套结构体的内存映射方式直接读取为v2。
方案1:C++环境(最贴合你要的Point1.XZ调用形式)
利用编译器属性扩展或成员访问函数即可实现,不需要修改原有内存布局,同时符合严格别名规则,没有未定义行为:
union v3 { struct { float x, y, z; }; struct { v2 xy; float Ignored0_; }; struct { float Ignored1_; v2 yz; }; float E[3]; // MSVC 编译器下用属性实现直接.XZ访问,和成员变量调用方式完全一致 __declspec(property(get = get_xz, put = set_xz)) v2 xz; // GCC/Clang 下可以用注释里的写法,调用时写 Point1.xz() 即可 // __attribute__((always_inline)) constexpr v2 xz() const noexcept { return {x, z}; } constexpr v2 get_xz() const noexcept { return v2{x, z}; } constexpr void set_xz(v2 value) noexcept { x = value.x; z = value.y; } };
调用时直接写Point1.xz即可拿到对应的v2值,也支持直接赋值:Point1.xz = (v2){1.0f, 2.0f};
方案2:纯C环境
纯C没有成员函数特性,可以用内联函数+宏的方式实现近似的调用效果:
static inline v2 v3_get_xz(const v3* vec) { return (v2){vec->x, vec->z}; } #define XZ(v) v3_get_xz(&v) // 赋值用辅助宏 #define SET_XZ(v, val) do { (v).x = (val).x; (v).z = (val).y; } while(0)
调用时写XZ(Point1)即可获得对应的v2值。
注意事项
不建议尝试用修改联合体内存布局的方式硬做跨间隔的v2映射,会违反C/C++的严格别名规则,触发未定义行为,在不同编译选项、不同编译器下可能出现异常结果。
内容的提问来源于stack exchange,提问作者Zhukov Artem
相关产品推荐
相关产品推荐

