Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constant integer trait in simple class

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; 
    };
};
like image 834
Robinson Avatar asked Feb 23 '26 16:02

Robinson


2 Answers

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.

like image 162
rodrigo Avatar answered Feb 25 '26 04:02

rodrigo


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.

like image 43
Nikos Athanasiou Avatar answered Feb 25 '26 06:02

Nikos Athanasiou



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!