强制 enum 为 unsigned long 类型

发布于 2024-10-19 06:05:56 字数 41 浏览 1 评论 0原文

是否可以强制枚举的基础类型为 unsigned long 类型?谢谢

Is it possible to force the underlying type of an enumeration to be unsigned long type? Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

时光与爱终年不遇 2024-10-26 06:05:56

在 C++11 及更高版本中,您可以显式提及您想要的类型:

enum MyEnumeration: unsigned long {
   /* ... values go here ... */
};

这将允许您显式控制基础类型。

在 C++03 中,无法强制枚举类型具有任何特定的底层实现。引用 C++03 规范,§7.2/5:

枚举的基础类型是整型,它可以表示枚举中定义的所有枚举器值。使用哪种整型作为枚举的基础类型是由实现定义的,但基础类型不得大于 int,除非枚举数的值无法容纳 int 或 unsigned int。如果枚举器列表为空,则基础类型就好像枚举具有值为 0 的单个枚举器。应用于枚举类型、枚举类型的对象或枚举器的 sizeof() 的值是sizeof() 应用于基础类型。

这是一个相当宽松的条件,它表明您不仅不一定知道该类型,而且因为它是实现定义的,所以无法保证它甚至根本对应于一种基本类型。

In C++11 and higher, you can explicitly mention what type you want:

enum MyEnumeration: unsigned long {
   /* ... values go here ... */
};

This will allow you to explicitly control the underlying type.

In C++03, there is no way to force an enumerated type to have any particular underlying implementation. Quoth the C++03 spec, §7.2/5:

The underlying type of an enumeration is an integral type that can represent all the enumerator values defined in the enumeration. It is implementation-defined which integral type is used as the underlying type for an enumeration 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 the enumerator-list is empty, the underlying type is as if the enumeration had a single enumerator with value 0. The value of sizeof() applied to an enumeration type, an object of enumeration type, or an enumerator, is the value of sizeof() applied to the underlying type.

This is a pretty lax condition and says that not only can you not necessarily know the type, but because it's implementation-defined there's no guarantee that it even corresponds to one of the primitive types at all.

橘和柠 2024-10-26 06:05:56

这可以根据您的编译器来实现。
它不适用于 Windows MSVS,但我测试了它,它适用于以下版本的 gcc/g++(加上嵌入式 cpp)编译器:

  • mipsel-openwrt-linux-uclibc-gcc.bin (OpenWrt/Linaro GCC 4.8- 2014.04 r47072) 4.8.3
  • g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
  • gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
  • avr-g++.exe (AVR_8_bit_GNU_Toolchain_ 3.5.4_1709 ) 4.9.2

通过将一个枚举定义为一个以 long 值表示的值,在某些编译器中它会强制它达到该大小。下面的代码通常输出:

8
4
4

来源:

#include <iostream>
using namespace std;

typedef enum
{
        ENUM_11,
        ENUM_12,

        enum1_force_long = 0x1122334455667788
} LongEnum1_t;

typedef enum
{
        ENUM_21,
        ENUM_22,

        enum2_force_long = 0x11223344
} LongEnum2_t;

typedef enum
{
        ENUM_31,
        ENUM_32,

        enum3_force_long = 0x1122
} LongEnum3_t;

LongEnum1_t enum1;
LongEnum2_t enum2;
LongEnum3_t enum3;
int main(void)
{
        cout << sizeof(enum1) << endl;
        cout << sizeof(enum2) << endl;
        cout << sizeof(enum3) << endl;

        return 0;
}

This can be achieved depending on your compiler.
It doesn't work with windows MSVS, but I tested it and it worked with the following versions of the gcc/g++ (plus embedded cpp) compiler:

  • mipsel-openwrt-linux-uclibc-gcc.bin (OpenWrt/Linaro GCC 4.8-2014.04 r47072) 4.8.3
  • g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
  • gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
  • avr-g++.exe (AVR_8_bit_GNU_Toolchain_3.5.4_1709) 4.9.2

By defining one of your enumerations to a value that would be represented in a long value, in some compilers it forced it to that size. The below code generally outputs:

8
4
4

Source:

#include <iostream>
using namespace std;

typedef enum
{
        ENUM_11,
        ENUM_12,

        enum1_force_long = 0x1122334455667788
} LongEnum1_t;

typedef enum
{
        ENUM_21,
        ENUM_22,

        enum2_force_long = 0x11223344
} LongEnum2_t;

typedef enum
{
        ENUM_31,
        ENUM_32,

        enum3_force_long = 0x1122
} LongEnum3_t;

LongEnum1_t enum1;
LongEnum2_t enum2;
LongEnum3_t enum3;
int main(void)
{
        cout << sizeof(enum1) << endl;
        cout << sizeof(enum2) << endl;
        cout << sizeof(enum3) << endl;

        return 0;
}
猫卆 2024-10-26 06:05:56

从 C++11 开始,您可以像这样执行 enum MyEnum : unsigned long

enum Color : int { red, green, blue };
Color r = red;
switch(r)
{
    case red  : std::cout << "red\n";   break;
    case green: std::cout << "green\n"; break;
    case blue : std::cout << "blue\n";  break;
}

参考:此处

Since C++11 you can do enum MyEnum : unsigned long like this:

enum Color : int { red, green, blue };
Color r = red;
switch(r)
{
    case red  : std::cout << "red\n";   break;
    case green: std::cout << "green\n"; break;
    case blue : std::cout << "blue\n";  break;
}

Reference: here

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文