2008-09-16 3 views
17

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

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

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

Есть ли причина предпочесть `неподписанный __int64` над` uint64_t`? Я думаю, что `uint64_t` определен для почти каждой соответствующей платформы, но` unsigned __int64` звучит как конкретное определение платформы (аппаратное обеспечение, компилятор или даже библиотека). – Johan 2017-04-07 09:51:47

ответ

14

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

const __int64 LARGE_VALUE = 0x1000000000000000L; 

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

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

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

+0

Это то, к чему я прибегал, в конце концов, но мне было любопытно, возможно ли 64-разрядное перечисление, даже с расширением для компилятора. – Rob 2008-09-16 21:14:37

0

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

enum MY_ENUM 
{ 
    CHAR_VALUE = 'c', 
}; 

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

enum MY_ENUM 
{ 
    LARGE_VALUE = 0x1000000000000000, 
}; 

По моему комментатору, sixlettervariables, в C базовый тип будет ИНТОМ всегда, в то время как в C++ базового типа является то, что является достаточно большим, чтобы вместить наибольшее включенное значение. Таким образом, обе передовицы выше должны работать.

+1

@Doug T .: в то время как ANSI C указывает, что перечисления представляют собой размер типа данных 'int', ISO C++ диктует, что перечисления имеют размер, по меньшей мере такой же большой, как требуется для представления всех значений. – user7116 2008-09-16 20:32:57

1

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

const __int64 LARVE_VALUE = ... 

Это может быть определено в файле H.

+0

Я обманул 9 символов с первой попытки. – Behrooz 2010-04-22 16:26:11

2

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

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

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

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

MyNamespace::LARGE_VALUE 

или

using MyNamespace; 
.... 
val = LARGE_VALUE; 
+1

И свободная безопасность типов. – 2010-02-10 13:33:49

+0

Несчастливо да – INS 2011-07-14 06:49:09

+2

Скорость нашего разговора напоминает мне переписка шахматы: D – 2011-07-14 07:05:33

1

ваш snipplet кода не C++ стандарт:

перечисление MY_ENUM: беззнаковое __int64

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

использование сопзЬ __int64 вместо этого, поскольку Torlack предлагает

+0

он довольно часто видел это на другом языке фигурных скобок (например, C# поддерживает его) или на предстоящем стандарте C++, где это будет разрешено. – 2010-02-10 13:36:01

17

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

enum class Enum2 : __int64 {Val1, Val2, val3}; 
+0

Тогда я был близок. Я должен где-то читать о синтаксисе `: type`. – Rob 2008-09-16 21:13:30

4

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

0

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

перечисление MYLONGLONGENUM: __ int64 {BIG_KEY = 0x3034303232303330, ...};

5

Нынешний проект так называемый C++0x, это n3092 говорит в 7,2 декларациях перечислимости, пункт 6:

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

В этом же пункте также говорится:

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

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

Например:

enum MyEnum 
{ 
    Undefined = 0xffffffffffffffffULL 
}; 
1

типа Enum, как правило, определяется типом данных первого перечисления инициализатора. Если значение должно превышать диапазон для этого интегрального типа данных, то компилятор C++ будет уверен, что он подходит, используя более крупный интегральный тип данных. Если компилятор считает, что он не принадлежит ни одному из целочисленных типов данных, то компилятор будет вызывать ошибку. Ref: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf
Edit: Но это чисто зависит от архитектуры машины