Инициализация объединения структур красиво - PullRequest
1 голос
/ 28 августа 2011

Я кодирую класс Vec3, и для целей оптимизации я делаю это без конструктора.Я также хотел бы иметь возможность получить доступ к его членам как x, y, z ИЛИ как r, g, b ИЛИ как вкладка.Легко, вы можете подумать: используйте объединение

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

Тогда, так как у меня нет ctor, я хотел бы инициализировать его так:

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

, но я должен поставить двойнойфигурные скобки, так как я инициализирую структуру в структуре (например: Vec3_t<int> v = {{1, 2, 3}})

Итак, мой вопрос : как я могу сделать это так, чтобы я мог иметь оба доступа сразные имена и инициализация с одной парой скобок?

моя попытка: иметь одно объединение для каждого компонента, но затем выйти с доступом как таблицей (всегда можно вызвать & v.x и рассматривать его как число с плавающей запятой)[3], но это немного грязно ... и не так безопасно, я думаю)

Ответы [ 3 ]

5 голосов
/ 28 августа 2011

Если ваш компилятор поддерживает эту функцию C ++ 11, вы можете создать конструктор, который принимает std::initializer_list (я знаю, вы сказали, что не хотите иметь конструктор, но это решение требует его [но я не не думаю, что это приведет к снижению производительности, если у вас есть оптимизация], извините):

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

Тогда вы можете построить Vec3_t так, как вы хотите:

Vec3_t<int> v = {1, 2, 3};
1 голос
/ 10 ноября 2011

Это не может быть сделано без конструктора, и это плохая идея, чтобы избежать использования ctor любой ценой.

0 голосов
/ 28 августа 2011

Самое близкое к инициализации класса без Ctor вы можете использовать три предопределенных объекта. Каждый инициализируется одним типом объединения, которое вы намереваетесь использовать. Присвойте один из желаемых видов новому объекту, который вы создаете.

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

T newT = t1;

Тем не менее, действительно трудно представить, почему у вас не может быть Ctor, кроме причины, по которой вы этого не хотите.

...