64-битное перечисление в С++?
Есть ли способ иметь 64-битное перечисление в С++? В то время как рефакторинг какого-то кода я натолкнулся на набор #defines, который был бы лучше как перечисление, но более 32 бит приводит к ошибке компилятора.
По какой-то причине я думал, что следующее может работать:
enum MY_ENUM : unsigned __int64
{
LARGE_VALUE = 0x1000000000000000,
};
Ответы
Ответ 1
Я не думаю, что это возможно с С++ 98. Основное представление перечислений зависит от компилятора. В этом случае вам лучше использовать:
const __int64 LARGE_VALUE = 0x1000000000000000L;
Как и в С++ 11, можно использовать классы enum для указания базового типа перечисления:
enum class MY_ENUM : unsigned __int64 {
LARGE_VALUE = 0x1000000000000000ULL
};
Кроме того, классы enum вводят новое пространство имен. Поэтому вместо ссылки на LARGE_VALUE
вы ссылаетесь на MY_ENUM::LARGE_VALUE
.
Ответ 2
С++ 11 поддерживает это, используя этот синтаксис:
enum class Enum2 : __int64 {Val1, Val2, val3};
Ответ 3
Текущая черновик так называемого С++ 0x, это n3092 говорит в 7.2. Объявления перечисления, пункт 6:
Определяется реализация, которая интегральный тип используется как базового типа, за исключением того, что базовый тип не должен быть больше чем int, если значение перечислитель не может вписываться в int или unsigned int.
В этом же параграфе также говорится:
Если интегральный тип не может представлять все значения перечислителя, перечисления плохо сформирован.
Моя интерпретация части , если значение перечислителя не может быть помещено в int или unsigned int, состоит в том, что он вполне корректен и безопасен для инициализации перечислителя с 64-битным целочисленным значением, если существует 64-разрядный целочисленный тип, предоставляемый в конкретной реализации на С++.
Например:
enum MyEnum
{
Undefined = 0xffffffffffffffffULL
};
Ответ 4
Ответы, относящиеся к __int64
, пропустят проблему. Перечисление действительна во всех компиляторах С++, имеющих истинный 64-битный интегральный тип, т.е. Любой компилятор С++ 11 или компиляторы С++ 03 с соответствующими расширениями. Расширения для С++ 03, такие как __int64
, работают по-разному для компиляторов, включая его пригодность в качестве базового типа для перечислений.
Ответ 5
Если компилятор не поддерживает 64-битные перечисления с помощью флагов компиляции или любых других средств, я думаю, что нет решения для этого.
Вы могли бы создать что-то вроде своего примера:
namespace MyNamespace {
const uint64 LARGE_VALUE = 0x1000000000000000;
};
и используя его так же, как enum, используя
MyNamespace::LARGE_VALUE
или
using MyNamespace;
....
val = LARGE_VALUE;
Ответ 6
Поскольку вы работаете на С++, другой альтернативой может быть
const __int64 LARVE_VALUE = ...
Это может быть указано в файле H.
Ответ 7
ваш snipplet кода не является стандартом С++:
enum MY_ENUM: unsigned __int64
не имеет смысла.
вместо этого используйте const __int64, поскольку Torlack предлагает
Ответ 8
Тип enum обычно определяется типом данных первого инициализатора перечисления. Если значение должно превышать диапазон для этого интегрального типа данных, то компилятор С++ будет уверен, что он подходит, используя более крупный интегральный тип данных. Если компилятор считает, что он не принадлежит ни одному из целочисленных типов данных, то компилятор будет вызывать ошибку.
Ссылка: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf
Edit: Однако это зависит исключительно от архитектуры машины
Ответ 9
Перечислением в С++ может быть любой интегральный тип. Вы можете, например, перечислить символы. IE:
enum MY_ENUM
{
CHAR_VALUE = 'c',
};
Я бы предположил, что это включает __int64. Попробуйте просто
enum MY_ENUM
{
LARGE_VALUE = 0x1000000000000000,
};
Согласно моему комментатору, sixlettervariables, в C базовый тип будет всегда int, тогда как в С++ базовый тип - это все, что достаточно велико, чтобы соответствовать наибольшему включенному значению. Таким образом, обе передовицы выше должны работать.
Ответ 10
В MSVС++ вы можете сделать это:
enum MYLONGLONGENUM: __ int64 {BIG_KEY = 0x3034303232303330,...};