【发布时间】:2014-01-28 18:12:34
【问题描述】:
我正在尝试实现一个 Vector 类以在我的图形项目中使用。我想按长度和类型对向量进行模板化,并且我希望能够使用 A.x、A.y、A.z、A.w 来访问向量 A 的成员(例如)。
这是我的第一次尝试。我绝对不是 C++ 模板方面的专家!我试图用 Vec2、Vec3 和 Vec4 的专用版本实现一个通用 Vector 类。每个专业类都有一个联合,允许我使用它们的名称访问坐标。不幸的是,如果不为每个专用类重新实现每个向量函数,我无法弄清楚如何做到这一点。
请记住,我想实现一些仅适用于特定长度向量的函数。例如,叉积仅适用于 vec3,而点积(或运算符*)适用于所有长度的向量。
#include <cstdint>
using namespace std;
//*********************************************************************
// Vector implementation parameterized by type and size.
//*********************************************************************
template <typename T, size_t SIZE>
class Vector {
public:
T data[SIZE];
size_t size;
Vector(T* arr);
};
template <typename T, size_t SIZE> Vector<T, SIZE>::Vector(T* arr) {
size = SIZE;
for(int i=0; i<size; i++) {
data[i] = arr[i];
}
}
//*********************************************************************
// Vec2 is a specialization of Vector with length 2.
//*********************************************************************
typedef Vector<float, 2> Vec2f;
typedef Vector<int, 2> Vec2d;
template <typename T>
class Vector <T, 2> {
public:
union {
T data[2];
struct {
T x;
T y;
};
};
size_t size;
Vector(T x, T y);
};
template <typename T> Vector<T, 2>::Vector(T x, T y) {
data[0] = x; data[1] = y;
size = 2;
}
//*********************************************************************
// Vec3 is a specialization of Vector with length 3.
//*********************************************************************
typedef Vector<float, 3> Vec3f;
typedef Vector<int, 3> Vec3d;
template <typename T>
class Vector <T, 3> {
public:
union {
T data[3];
struct {
T x;
T y;
T z;
};
};
size_t size;
Vector(T x, T y, T z);
};
template <typename T> Vector<T, 3>::Vector(T x, T y, T z) {
data[0] = x; data[1] = y; data[2] = z;
size = 3;
}
//*********************************************************************
// Vec4 is a specialization of Vector with length 4.
//*********************************************************************
typedef Vector<float, 4> Vec4f;
typedef Vector<int, 4> Vec4d;
template <typename T>
class Vector <T, 4> {
public:
union {
T data[4];
struct {
T x;
T y;
T z;
T w;
};
};
size_t size;
Vector(T x, T y, T z, T w);
};
template <typename T> Vector<T, 4>::Vector(T x, T y, T z, T w) {
data[0] = x; data[1] = y; data[2] = z; data[3] = w;
size = 4;
}
【问题讨论】:
-
这不是继承可以解决的问题吗? Vector2 将是基础。让vector3继承vector2的成员并添加到它上面。 Vector4 继承 vector3 并添加到它。我能看到 atm 的唯一开销是虚拟通话。
-
您应该为自己节省大量时间并使用
std::vector。它是免费的,已经实施,并且已经过测试。 -
@ThomasMatthews OP 正在尝试实现数学向量,而不是容器。
-
您当前对联合的使用肯定会引入未定义的行为。
-
我记得联合中的匿名结构不是标准的?