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

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

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

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

Есть ли причина предпочесть unsigned __int64 перед uint64_t? Я думаю, что uint64_t определен почти для каждой соответствующей платформы, но unsigned __int64 звучит как определение конкретной платформы (аппаратного обеспечения, компилятора или даже библиотеки).

Johan 07.04.2017 12:51
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
19
1
26 965
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

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

enum MY_ENUM
{
   CHAR_VALUE = 'c',
};

Я бы сказал, что предполагать включает __int64. Попробуй просто

enum MY_ENUM
{
   LARGE_VALUE = 0x1000000000000000,
};

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

@Doug T .: в то время как ANSI C диктует, что перечисления имеют размер типа данных 'int', ISO C++ диктует, что размер перечислений должен быть не меньше размера, необходимого для представления всех значений.

user7116 17.09.2008 00:32
Ответ принят как подходящий

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

const __int64 LARGE_VALUE = 0x1000000000000000L;

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

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

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

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

Rob 17.09.2008 01:14

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

const __int64 LARVE_VALUE = ...

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

Я обманул 9 символов с первой попытки.

Behrooz 22.04.2010 20:26

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

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

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

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

MyNamespace::LARGE_VALUE 

или же

using MyNamespace;
....
val = LARGE_VALUE;

И все же слабая безопасность типов.

Sebastian Mach 10.02.2010 16:33

Скорость нашего разговора мне напоминает заочные шахматы: D

Sebastian Mach 14.07.2011 11:05

ваш фрагмент кода не является стандартом С ++:

enum MY_ENUM : unsigned __int64

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

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

он часто видел это в другом языке фигурных скобок (например, C# поддерживает это) или в готовящемся стандарте C++, где это будет разрешено.

Sebastian Mach 10.02.2010 16:36

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

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

Тогда я был близок. Я должен где-нибудь прочитать о синтаксисе : type.

Rob 17.09.2008 01:13

обратите внимание, что class по-прежнему не является обязательным. Если вам нужно перечисление в старом стиле, но с настраиваемым типом, вы также можете enum moo : long long {...}

Sebastian Mach 10.02.2010 16:32

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

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

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

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

It is implementation-defined which integral type is used as the underlying type except that the underlying type shall not be larger than int unless the value of an enumerator cannot fit in an int or unsigned int.

В том же абзаце также говорится:

If no integral type can represent all the enumerator values, the enumeration is ill-formed.

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

Например:

enum MyEnum
{
    Undefined = 0xffffffffffffffffULL
};

Если вы не хотите отсчитывать свои f, вы можете просто сделать Undefined = ~0x0ULL

Cory-G 01.08.2014 02:51

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

Другие вопросы по теме