Принудительное перечисление типа unsigned long - PullRequest
14 голосов
/ 23 февраля 2011

Можно ли заставить базовый тип перечисления быть типом unsigned long?Спасибо

Ответы [ 3 ]

29 голосов
/ 23 февраля 2011

В C ++ 03 нет способа заставить перечисляемый тип иметь какую-либо конкретную базовую реализацию. Quoth C ++ spec & sect; 7.2 / 5:

Базовый тип перечисления является целочисленным типом, который может представлять все значения перечислителя, определенные в перечислении. определяется реализацией, какой интегральный тип используется в качестве базового типа для перечисления, за исключением того, что базовый тип не должен быть больше, чем int, если только значение перечислителя не может поместиться в int или unsigned int. Если список-перечислитель пуст, базовый тип выглядит так, как если бы перечисление имело единственный перечислитель со значением 0. Значение sizeof (), примененное к типу перечисления, объекту типа перечисления или перечислителю, является значением sizeof () применяется к базовому типу.

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

Однако в C ++ 0x это исправлено, так что вы можете явно указать, какой тип вам нужен:

enum MyEnumeration: unsigned long {
   /* ... values go here ... */
};

Это позволит вам явно контролировать базовый тип.

1 голос
/ 01 марта 2017

Это может быть достигнуто в зависимости от вашего компилятора. Он не работает с Windows MSVS, но я протестировал его и работал со следующими версиями компилятора gcc / g ++ (плюс встроенный cpp):

  • mipsel-openwrt-linux-uclibc-gcc.bin (OpenWrt / Linaro GCC 4.8-2014.04 r47072) 4.8.3
  • g ++ (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.4) 5.4.0 20160609
  • gcc (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.4) 5.4.0 20160609
  • avr-g ++. Exe (AVR_8_bit_GNU_Toolchain_3.5.4_1709) 4.9.2

Определив одно из ваших перечислений в значении, которое будет представлено в длинном значении, в некоторых компиляторах оно принудительно привело к этому размеру. Код ниже, как правило, выводит:

8
4
4

Источник:

#include <iostream>
using namespace std;

typedef enum
{
        ENUM_11,
        ENUM_12,

        enum1_force_long = 0x1122334455667788
} LongEnum1_t;

typedef enum
{
        ENUM_21,
        ENUM_22,

        enum2_force_long = 0x11223344
} LongEnum2_t;

typedef enum
{
        ENUM_31,
        ENUM_32,

        enum3_force_long = 0x1122
} LongEnum3_t;

LongEnum1_t enum1;
LongEnum2_t enum2;
LongEnum3_t enum3;
int main(void)
{
        cout << sizeof(enum1) << endl;
        cout << sizeof(enum2) << endl;
        cout << sizeof(enum3) << endl;

        return 0;
}
0 голосов
/ 06 декабря 2018

Начиная с C ++ 11 вы можете сделать enum MyEnum : unsigned long следующим образом:

enum Color : int { red, green, blue };
Color r = red;
switch(r)
{
    case red  : std::cout << "red\n";   break;
    case green: std::cout << "green\n"; break;
    case blue : std::cout << "blue\n";  break;
}

Ссылка: здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...