如何实现带XYZW/RGBA成员访问的模板化数学Vector类?
模板化数学Vector类实现方案
针对你需要的模板化数学Vector类,这里提供一个基于匿名联合+模板特化+基类复用的实现,解决内存分离问题,且无重复代码:
核心思路
- 用基类
VectorBase封装所有通用逻辑(下标运算符、迭代器、构造逻辑等),避免重复代码 - 主模板
Vector继承基类,内部用匿名联合存储数组;针对大小3、4的情况做特化,在联合中添加对应的.x/.y/.z等成员变量,确保数组和成员共享同一块内存 - 非3、4大小的Vector仅保留数组和下标访问,符合需求
完整代码实现
#include <cstddef> #include <stdexcept> #include <cassert> // 通用基类:封装所有跨大小的通用逻辑 template <typename T, size_t N> class VectorBase { protected: T* m_data; public: explicit VectorBase(T* data) : m_data(data) {} // 下标运算符 T& operator[](size_t idx) { if (idx >= N) throw std::out_of_range("Vector index out of bounds"); return m_data[idx]; } const T& operator[](size_t idx) const { if (idx >= N) throw std::out_of_range("Vector index out of bounds"); return m_data[idx]; } // 迭代器支持 T* begin() { return m_data; } const T* begin() const { return m_data; } T* end() { return m_data + N; } const T* end() const { return m_data + N; } // 类型别名 using value_type = T; using size_type = size_t; }; // 主模板:默认大小的Vector,仅含数组 template <typename T, size_t N> class Vector : public VectorBase<T, N> { union { T data[N]; }; public: Vector() : VectorBase<T, N>(data) {} explicit Vector(const T(&arr)[N]) : VectorBase<T, N>(data) { for (size_t i = 0; i < N; ++i) data[i] = arr[i]; } }; // 特化:大小为3的Vector,添加x/y/z和r/g/b成员 template <typename T> class Vector<T, 3> : public VectorBase<T, 3> { union { T data[3]; struct { T x, y, z; }; struct { T r, g, b; }; }; public: Vector() : VectorBase<T, 3>(data) {} explicit Vector(const T(&arr)[3]) : VectorBase<T, 3>(data) { for (size_t i = 0; i < 3; ++i) data[i] = arr[i]; } }; // 特化:大小为4的Vector,添加x/y/z/w和r/g/b/a成员 template <typename T> class Vector<T, 4> : public VectorBase<T, 4> { union { T data[4]; struct { T x, y, z, w; }; struct { T r, g, b, a; }; }; public: Vector() : VectorBase<T, 4>(data) {} explicit Vector(const T(&arr)[4]) : VectorBase<T, 4>(data) { for (size_t i = 0; i < 4; ++i) data[i] = arr[i]; } }; // 测试代码 int main() { Vector<float, 3> v3{1.0f, 2.0f, 3.0f}; v3.x = 5.0f; assert(v3[0] == 5.0f); assert(v3.r == 5.0f); Vector<double, 4> v4{1.0, 2.0, 3.0, 4.0}; v4.w = 10.0; assert(v4[3] == 10.0); assert(v4.a == 10.0); Vector<int, 2> v2{1, 2}; v2[0] = 3; // v2.x; // 编译错误,符合预期 }
方案优势
- 内存连续:匿名联合确保数组和成员变量共享同一块内存,彻底解决之前继承方案的内存分离问题
- 无重复代码:所有通用逻辑都在
VectorBase中,特化类仅需添加成员定义和简单构造 - 严格的访问控制:非3、4大小的Vector无法访问
.x/.y等成员,编译期就会报错 - 原生成员访问:
.x/.y等都是普通成员变量,无需通过函数调用访问,性能无损耗
内容的提问来源于stack exchange,提问作者Joel
相关产品推荐
相关产品推荐

