I'm trying to implement a Vector class for use in my graphics projects. I'd like to template the vector by length and type, and I'd like to be able to use A.x, A.y, A.z, A.w to access the members of vector A (for example).
Here's my first attempt. I'm definitely not an expert in C++ templates! I was trying to implement a general Vector class with specialized versions for Vec2, Vec3, and Vec4. Each of the specialized classes would have a union allowing me to access the coordinates using their names. Unfortunately, I can't figure out how to do this without re-implementing every vector function for each of the specialized classes.
Keep in mind that I want to implement some functions that only apply to vectors of a certain length. For example, cross product only applies to vec3, but dot product (or operator*) applies to vectors of all length.
#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;
}