64-битное перечисление в C ++? - PullRequest
       19

64-битное перечисление в C ++?

18 голосов
/ 17 сентября 2008

Есть ли способ получить 64-битное перечисление в C ++? При рефакторинге некоторого кода я натолкнулся на кучу #defines, которые были бы лучше в качестве перечисления, но превышение 32 бит приводит к ошибке компилятора.

По какой-то причине я подумал, что может сработать следующее:

enum MY_ENUM : unsigned __int64  
{  
    LARGE_VALUE = 0x1000000000000000,  
};

Ответы [ 10 ]

17 голосов
/ 17 сентября 2008

C ++ 11 поддерживает это, используя этот синтаксис:

enum class Enum2 : __int64 {Val1, Val2, val3};
17 голосов
/ 17 сентября 2008

Я не думаю, что это возможно с C ++ 98. Основное представление перечислений зависит от компилятора. В этом случае вам лучше использовать:

const __int64 LARGE_VALUE = 0x1000000000000000L;

Начиная с C ++ 11, можно использовать классы enum для указания базового типа перечисления:

enum class MY_ENUM : unsigned __int64 {
    LARGE_VALUE = 0x1000000000000000ULL
};

Кроме того, классы enum вводят новую область имен. Поэтому вместо ссылки на LARGE_VALUE вы бы ссылались на MY_ENUM::LARGE_VALUE.

5 голосов
/ 13 апреля 2010

Текущий черновик так называемого C ++ 0x , это n3092 говорит в 7.2 Объявления перечисления , параграф 6:

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

В том же абзаце также сказано:

Если ни один целочисленный тип не может представлять все значения перечислителя, перечисление плохо сформирован.

Моя интерпретация части , если только значение перечислителя не может поместиться в int или unsigned int , заключается в том, что вполне допустимо и безопасно инициализировать перечислитель 64-разрядным целочисленным значением, если существует 64 -битный целочисленный тип, предоставляемый в конкретной реализации C ++.

Например:

enum MyEnum
{
    Undefined = 0xffffffffffffffffULL
};
4 голосов
/ 17 сентября 2008

Ответы на __int64 пропускают проблему. Перечисление является допустимым во всех компиляторах C ++, которые имеют истинный 64-битный целочисленный тип, то есть любой компилятор C ++ 11 или компиляторы C ++ 03 с соответствующими расширениями. Расширения до C ++ 03, такие как __int64, работают по-разному в разных компиляторах, включая его пригодность в качестве базового типа для перечислений.

2 голосов
/ 17 сентября 2008

Если компилятор не поддерживает 64-битные перечисления по флагам компиляции или любым другим способом, я думаю, что нет никакого решения для этого.

Вы можете создать что-то вроде в вашем примере что-то вроде:

namespace MyNamespace {
const uint64 LARGE_VALUE = 0x1000000000000000;
};

и использование его как перечисление с использованием

MyNamespace::LARGE_VALUE 

или

using MyNamespace;
....
val = LARGE_VALUE;
1 голос
/ 07 декабря 2012

Тип перечисления обычно определяется типом данных первого инициализатора перечисления. Если значение должно превышать диапазон для этого интегрального типа данных, то компилятор c ++ удостоверится, что оно подходит, используя больший тип интегральных данных. Если компилятор обнаружит, что он не принадлежит ни к одному из целочисленных типов данных, компилятор выдаст ошибку. Ссылка: http://www.open -std.org / jtc1 / sc22 / wg21 / docs /apers / 2005 / n1905.pdf
Редактировать: Однако это зависит только от архитектуры машины

1 голос
/ 17 сентября 2008

ваш фрагмент кода не соответствует стандарту c ++:

enum MY_ENUM: без знака __int64

не имеет смысла.

вместо этого используйте const __int64, как предлагает Торлак

1 голос
/ 17 сентября 2008

Поскольку вы работаете в C ++, другой альтернативой может быть

const __int64 LARVE_VALUE = ...

Это можно указать в файле H.

0 голосов
/ 24 сентября 2009

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

enum MYLONGLONGENUM: __ int64 {BIG_KEY = 0x3034303232303330, ...};

0 голосов
/ 17 сентября 2008

Перечисление в C ++ может быть любым целым типом. Вы можете, например, иметь набор символов. IE:

enum MY_ENUM
{
   CHAR_VALUE = 'c',
};

Я бы предположил , включая __int64. Попробуйте просто

enum MY_ENUM
{
   LARGE_VALUE = 0x1000000000000000,
};

Согласно моему комментатору, Sixlettervariables, в C базовый тип всегда будет int, в то время как в C ++ базовый тип достаточно большой, чтобы соответствовать наибольшему включенному значению. Так что оба перечисленных выше значения должны работать.

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