I am creating a Vector class and instead of creating separate classes for Vector2, Vector3 and Vector4 I want to make an all-in-one class. My problem is that I want to define certain properties depending on the size of the vector. For example, a vector of size 2 will have an x and y component, but not a z component.
I'm attempting to use the #if directive to check the non-type template argument (SIZE) to create properties depending on the size of the vector. I did some research and I don't think it's possible this way. I'm wondering if anyone has an idea about how to achieve want I want?
template <typename T, int SIZE>
class Vector
{
public:
union
{
struct
{
#if SIZE == 2
T x, y;
#endif
#if SIZE == 3
T z;
#endif
#if SIZE == 4
T w;
#endif
};
T data[SIZE];
};
};
I want to be able to create and access a Vector like so:
Vector<int, 2> vec2;
vec2.x;
Vector<int, 3> vec3;
vec3.z;
Any feedback is appreciated!
EDIT: After reviewing the comments I came up with a nifty solution... Hopefully it works for me. I created a templated class:
template <typename T, unsigned int SIZE> class _vec;
This deals with the data (components) of the vector and contains the behaviour. Then I made another templated class that will sort of specialise _vec like so:
template <typename T, unsigned int SIZE> class Vector : public _vec<T, SIZE>;
This is a vector of any size. Now I can specialise that for Vector2, Vector3 and Vector4:
template <typename T> class Vector<T, 2> : public _vec<T, 2>;
template <typename T>
using Vector2 = Vector<T, 2>;
I'll let you know how HORRIBLE this will turn out... ;P
EDIT 2: It worked, but didn't work out... :(
No, this is not possible.
In the phases of translation, the preprocessing phase comes before the template instantiation phase. So in this case, you will end up having none of the variables defined in the template Vector because SIZE is not defined at the preprocessing phase.
As per the C++ standard, [cpp.cond]/9:
After all replacements due to macro expansion and evaluations of defined-macro-expressions and has-include-expressions have been performed, all remaining identifiers and keywords, except for
trueandfalse, are replaced with the pp-number0, and then each preprocessing token is converted into a token.
So the value of SIZE here will be 0 and thus none of the conditions of the conditional inclusions are met.
You can instead specialize your template to have different variables for different instantiations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With