Given the following simple declaration, is it possible to give the class a constant integer trait specifying the number of components (2 in this case)? Vec3 and Vec4 would have 3 and 4 respectively. I just want this as a compile-time constant for instantiating other templates in various ways. It doesn't have to be there at runtime.
template<class T>
struct Vec2
{
typedef T value_type;
typedef unsigned index_type;
struct
{
T x, y;
};
};
The most portable way would be to add an enum constant:
template<class T> struct Vec2
{
enum { num_components = 2 };
};
template<class T> struct Vec3
{
enum { num_components = 3 };
};
Then just use V::num_components where needed.
If you are into C++11 then you can also use static const int num_components = 2; instead of an anonymous enum, but if you need compatibility with old compilers, then the enum idiom will save you some headaches.
A solution would have you specifying policies to do exactly that
// base class to store members
template<size_t N>
struct Coords;
template<>
struct Coords<2> {
double x, y;
};
template<>
struct Coords<3> {
double x, y, z;
};
template<>
struct Coords<4> {
double x, y, z, w;
};
// members depend on your base class
template<class T, size_t N>
struct Vec : Coords<N>
{
using num = integral_constant<size_t, N>;
};
Now the following exists per type (note that num is a type so it doesn't occupy any space) :
Vec<2> -> x, y and num::value = 2 (`constexpr` - compile time usable)
Vec<3> -> x, y, z and num::value = 3 //
Vec<4> -> x, y, z, w and num::value = 4 //
Unless you specifically want the named members style I'd suggest using a meber that contains all values, like
double _coords[N]; // N is a compile time constant so you can have arrays
because such a solution would be more scalable, generic and easier to code.
PS I'm using double in place of T to simplify the examples.
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