Zonko
Zonko

Reputation: 3693

Initializing union of structs nicely

I'm coding a Vec3 class, and for optimization purpose, I make it with no constructor. I also would like to be able to access its members as x, y, z OR as r, g, b OR as a tab. Easy, you might think : use a union

template <typename T> struct Vec3_t    
{    
    union    
    {
        T val[3];    
        struct { T x, y, z; };    
        struct { T r, g, b; };    
    };
};

Then, since I have no ctor, I would like to initialize it like this :

Vec3_t<int> v = {1, 2, 3};

but I have to put double braces since I'm initializing a struct in a struct (like this : Vec3_t<int> v = {{1, 2, 3}} )

So, my question is : How could I do it so that I can have both access with different names, and initialization with one pair of braces ?

my try : having one union for each component, but then exit with the access as a table (one can always call &v.x and treat it as a float[3], but that's kind of dirty... and not so safe I guess)

Upvotes: 1

Views: 1900

Answers (3)

Zonko
Zonko

Reputation: 3693

It cannot be done without a constructor, and it is a bad idea to avoid using a ctor at all costs.

Upvotes: 1

Ajeet Ganga
Ajeet Ganga

Reputation: 8653

The closest you can get to initializing a class without a Ctor is use three predefined objects. Each one initialized to one type of union you intend to use. Assign one of the desired kind to new object your are creating.

T t1;// array
T t2;// xyz
T t3;// rgb

T newT = t1;

That said, it is really difficult to imagine why you can not have Ctor, other than the reason you do not want it.

Upvotes: 0

Seth Carnegie
Seth Carnegie

Reputation: 75130

If your compiler supports this feature of C++11, you can create a constructor that takes an std::initializer_list (I know you said you didn't want to have a constructor, but this solution requires one [but I don't think it cause a performance hit at all if you have optimisations on], sorry):

Vec3_t(std::initializer_list<T> list) : val(list) { }

Then you can construct a Vec3_t like you want:

Vec3_t<int> v = {1, 2, 3};

Upvotes: 5

Related Questions