Как я могу назначить целое без знака для перечисления в C ++? - PullRequest
4 голосов
/ 10 ноября 2011

В библиотеке C ++, чьи внутренние компоненты я переписываю, у меня есть несколько целочисленных переменных без знака, которые я хочу преобразовать в перечисления:

enum InitType {
    INIT,
    NON_INIT
};

и у меня есть переменная этого типа:

InitType InitVar;

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

uint32_t UnsignedIntVar;

Я хочу назначить неподписанную версию, которая была передана вызывающей стороной, внутреннему перечислению библиотек:

InitVar = UnsignedIntVar;

Но компилятору это не нравится:

error: invalid conversion from 'uint32_t' to 'InitType'

Какой самый чистый способ выполнить это преобразование?


Вот несколько идей, которые у меня были:

Если enum имеет только два значения, я могу сделать это так:

    InitVar = UnsignedIntVar ? Init : NonInit;

Это много написано в любое время, когда я хочу сделать такое назначение.

Если у него больше значений, я могу создать таблицу перевода:

InitType Uint2InitTypeConv = {INIT_0, INIT_1, INIT_2...};

Где INIT_x - это просто имена перечислений. Тогда я могу перевести с помощью таблицы:

InitVar = Uint2InitTypeConv[UnsignedIntVar];

Это кажется довольно чистым. Тем не менее, я полагаю, что я должен быть в состоянии перегрузить operator= для этого, но я не могу понять, что это правильно. Это легко заключит в себе любое другое безобразие, которое я могу придумать.

Ответы [ 2 ]

13 голосов
/ 10 ноября 2011

Вы можете преобразовать в перечисления явно :

InitType i = InitType(UnsignedIntvar);

Если целое число не имеет значения, соответствующего известному значению перечисления, это ваша проблема.

Типичным случаем, когда это вполне приемлемо, является циклическое перечисление:

enum ESomething { Default = 0, Something, SomeOtherThing };
for (int i = 0; i != 3; ++i)
{
  ESomething e = ESomething(i);
  // do something with "e"
}
1 голос
/ 10 ноября 2011
InitVar = UnsignedIntVar ? Init : NonInit;

Это много написано в любое время, я хочу сделать такое назначение.

Да, но, поскольку значение для uint32_t отличается от значения вашего enum, я бы все равно это сделал. Как говорят в сообществе Python, «явное лучше, чем неявное». Я не буду выполнять приведение, и табличный подход страдает недостатком, заключающимся в том, что вам нужно перечислить все значения uint32_t, чтобы получить полное покрытие, что было бы практически невозможно.

Почему бы не ввести функцию с соответствующим именем для преобразования? Что-то вроде InitType init_type(uint32_t), реализованное как switch?

...