2012-03-24 2 views
16

Если у меня есть C++ перечисление:Как изменить целочисленный тип, используемый enum (C++)?

enum Foo 
{ 
    Bar, 
    Baz, 
    Bork, 
}; 

Как сказать компилятору использовать uint16_t фактически хранить значение перечисления?

EDIT: поддерживает ли GCC эту функцию при реализации C++ 11?

+1

@YochaiTimmer, стандарт изменен и тема по ссылке не говорит о 'enum class' – Lol4t0

+0

@YochaiTimmer: совсем нет. Я хочу знать, могу ли я изменить enum для сохранения своих значений внутри с помощью 'uint16_t', а не того же размера, что и' int'. – Linuxios

ответ

23

Вы не можете сделать это на C++ 98/03 , C++ 11 действительно позволяет сделать это, и безenum class, как все остальные, кажется, говорю вам:

enum EnumType : uint16_t 
{ 
    Bar, 
    Baz, 
    Bork, 
}; 

Опять же, вы не должны использовать enum class. Не то, чтобы это плохая идея, но у вас нет есть.


ли GCC поддерживает эту функцию в реализации C++ 11?

Which version of GCC? Похоже, что GCC 4.4 добавил эту функциональность, но вы, вероятно, должны смотреть на более свежие версии только ради стабильности.

+0

Мне было интересно, что я. Единственное отличие состоит в том, что 'enum class' создает новую область, тогда как' enum' не делает. – chris

+3

@chris: Нет, существует несколько различий между 'enum class' и' enum'. Оба они создают области (к приведенному выше «Бару» можно получить доступ с помощью «EnumType :: Bar»), но только версия 'class' * заставляет * использовать область с перечислением. Кроме того, переменные 'enum class' не * неявно * конвертируют целые числа в тип перечисления. Таким образом, вы должны либо передать фактический счетчик правильного типа, либо выполнить явное приведение. Это добавляет * много больше безопасности. –

+0

О, я получил свою точку зрения от другого вопроса о SO: http://stackoverflow.com/questions/441552/scope-resolution-operator-on-enums-a-compiler-specific-extension Что касается вашего второго момента, я просто никогда не слышал об этом. Спасибо за бесплатное знание :) – chris

5

С c++11 теперь у вас есть enum class, что позволяет установить базовый тип явно:

enum class Foo: uint16_t 
{ 
    Bar, 
    Baz, 
    Bork, 
}; 
13

В C++ 11, вы можете сделать это:

enum class Foo : uint16_t 
{ 
    Bar, 
    Baz, 
    Bork, 
}; 

Позже, вы можете также know the underlying type of the enum as:

#include <type_traits> 

std::underlying_type<Foo>::type v = 10; //v is uint16_t 
+3

+1 для добавления запроса 'basic_type'. –

5

С предварительными C++ 2011 вы можете заставить минимальное хранение, используя подходящий диапазон значений:

enum foo { 
    v0 = 0, 
    vmax = 32767 
}; 

Я думаю, что компилятор волен выбирать либо знак или беззнаковый целое число типа, как базовый тип. В приведенном выше диапазоне было установлено, что в представлении используется как минимум short как базовое целое число. Сделать его еще одним большим может привести к его использованию long. Конечно, это только заставляет минимальный диапазон, и компилятор может выбрать более широкий диапазон. Кроме того, с приведенным выше определением вам не разрешается заходить за пределы диапазона [0, 32767]: если вам действительно нужен 16-битный диапазон (по крайней мере), вам нужно использовать соответствующие значения).

+1

На самом деле, существует ограничение на размер базового типа. [dcl.enum]/6 уточняет: кроме того, что базовый тип не должен быть больше, чем 'int', если значение перечислителя не может быть помещено в' int' или 'unsigned int'. –

Смежные вопросы