Inicializando la unión de estructuras muy bien

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    
        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}} )

Entonces, mi pregunta es : 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)

preguntado el 28 de agosto de 11 a las 00:08

Premature optimization is the root of all evil. This is a template class, so the source of the constructor will be available at compile time. Most modern compilers will use all this information to generate optimal code. Save yourself some time and write a constructor. -

Actually, I didn't want a ctor so that when I do a 'new Vec3_t[x]', nothing gets called. But I just made a little test, and it seems that having an empty default ctor allows the same... I guess I'll go for a ctor. -

@Zonko if my answer below solved your problem, would you please click the checkmark beside it (just underneath the up and down arrows) to mark it as the answer? -

@Zonko - yes, write a default constructor that takes no arguments and does nothing. Your compiler is probably inlining the call, which will result in inlining nothing. Note that for a non-template class this may not be the case. However, for a non-template class, you can define the empty constructor in the header file and this probably yields the same optimisation. -

3 Respuestas

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};

Respondido 28 ago 11, 04:08

If you allow a constructor, you could just get it to accept Vec3_t<int> v(1,2,3);... - Kerrek SB

@Kerrek true. I don't know why he doesn't want a constructor though, such simple code wouldn't be any slower than initializing an array would it? - Seth Carnegie

This does not answer the question : you solve the problem with a ctor. As Kerrek said, if you use a ctor you can just make it "normal". - Zonko

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

respondido 10 nov., 11:21

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.

Respondido 28 ago 11, 05:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.