C++中的64位枚举?

20

在C++中,是否有一种方式可以使用64位枚举?当我重构代码时,我发现一堆#定义最好改为枚举,但是超过32位会导致编译器报错。

出于某种原因,我认为以下方法可能有效:

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

1
有没有理由更喜欢使用 unsigned __int64 而不是 uint64_t?我认为 uint64_t 已经被定义在几乎所有相关平台上,但是 unsigned __int64 听起来像是一个特定于平台(硬件、编译器或甚至库)的定义。 - Johan
@Johan __int64 是 Microsoft-C++ 中对于 long long 的特定别名。 - ManuelAtWork
10个回答

18

我认为使用C++98无法实现这一点。枚举类型的底层表示取决于编译器。在这种情况下,最好使用:

const __int64 LARGE_VALUE = 0x1000000000000000L;

自 C++11 开始,可以使用枚举类(enum classes)来指定枚举的基础类型:

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

此外,枚举类引入了新的名称空间。所以,您不再引用LARGE_VALUE,而是应该引用MY_ENUM::LARGE_VALUE


这是我最终采用的方法,但我很好奇是否仍然有可能使用编译器特定的扩展来实现64位枚举。 - Rob
MSVC 8(2005年)已支持底层类型作为非标准扩展。 - ManuelAtWork

18

C++11支持这一特性,使用以下语法:

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

我差点就成功了。我一定在某个地方读到过 : type 语法。 - Rob
6
请注意,“class”仍是可选的。如果您想要旧风格的枚举,但使用自定义类型,您也可以这样做:“enum moo : long long {...}”。 - Sebastian Mach

8

目前所谓的C++0x草案,在7.2枚举声明第6段中,n3092表示:

具体实现使用的整数类型是由实现定义的,但其底层类型不应大于int,除非枚举值无法适合于int或unsigned int。

同一段还说到:

如果没有整数类型可以表示所有的枚举值,则枚举形式是不良构的。

我对除非枚举值无法适合于int或unsigned int的部分的理解是:只要特定C++实现提供了64位整数类型,就可以完全有效和安全地使用64位整数值初始化枚举器。

例如:

enum MyEnum
{
    Undefined = 0xffffffffffffffffULL
};

4
如果您不想数清您的f,可以使用Undefined = ~0x0ULL - Cory-G

4

有关__int64的答案忽略了问题。枚举类型在所有具有真正的64位整数类型的C++编译器中都是有效的,即任何C++11编译器或具有适当扩展的C++03编译器。C++03的扩展,如__int64在不同的编译器中有不同的工作方式,包括其作为枚举类型基础类型的适用性。


2
如果编译器在编译标志或其他方式下不支持64位枚举,我认为这是没有解决方案的。
您可以创建类似于示例中的内容,例如:
namespace MyNamespace {
const uint64 LARGE_VALUE = 0x1000000000000000;
};

并且可以像使用枚举一样使用它

MyNamespace::LARGE_VALUE 

或者
using MyNamespace;
....
val = LARGE_VALUE;

1
但是会失去类型安全。 - Sebastian Mach
2
我们的对话速度让我想起了邮件国际象棋 :D - Sebastian Mach

1

枚举类型通常由第一个枚举初始化器的数据类型确定。如果该值超出了整数数据类型的范围,则C++编译器将使用更大的整数数据类型来确保它适合其中。如果编译器发现它不属于任何整数数据类型,则编译器将抛出错误。 参考:http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf
编辑:然而,这完全取决于机器架构。


1

由于您正在使用C++,另一个选择可能是

const __int64 LARVE_VALUE = ...

这可以在一个H文件中指定。


我第一次尝试就用了9个字符作弊。 - Behrooz

1

你的代码片段不符合C++标准:

枚举MY_ENUM:unsigned __int64

没有意义。

像Torlack建议的那样,使用const __int64代替。


他可能已经在另一种花括号语言(例如C#)中看到过它,或者在即将发布的C++标准中,这将是允许的。 - Sebastian Mach

0

C++中的枚举可以是任何整数类型。例如,您可以有一个字符枚举。即:

enum MY_ENUM
{
   CHAR_VALUE = 'c',
};

我会认为这包括__int64。只需尝试

enum MY_ENUM
{
   LARGE_VALUE = 0x1000000000000000,
};

根据我的评论者sixlettervariables所说,在C中基本类型总是int,而在C ++中基本类型是足够大以适应最大包含值的任何类型。因此上面两个枚举都应该起作用。

1
@Doug T.:虽然 ANSI C 规定枚举类型的大小与 'int' 数据类型相同,但 ISO C++ 规定枚举类型的大小至少要足以表示所有值。 - user7116

0
在MSVC++中,你可以这样做:
枚举MYLONGLONGENUM:__int64 { BIG_KEY=0x3034303232303330, ... };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接