6

对于从未写过一行 C++11 并且目前还没有机会使用 C++11 编程的人,你能用一小段话告诉我:

什么是“枚举类”,我们为什么需要它?

4

4 回答 4

14

enum class称为作用域枚举。它可以防止使用枚举器的名称污染枚举出现的名称空间。

在 C++03 中,您可以通过在enum内部放置一个专用的class. 也许这就是语法的来源,这有点令人困惑。

另一个区别是这种类型的枚举数不会隐式转换为int(static_cast<int>是必需的)。这可能很少需要,但它可以安全地重载一个int带有一个参数enum类型的函数。您可以确定int不会被意外调用。或者您可以使用专用函数定义伪整数类型operator,并确保内置运算符不会干扰。

这两个不相关的差异出现在同一个包中有点烦人,并且您无法在没有隐式转换的情况下获得无范围的枚举,但通常这两个更改都是好事,并且enum class是 C++11 中的一个很好的默认做法。

编辑:范围枚举定义如下:

enum class duck { huey, dewey, louie };

并且必须与范围解析运算符一起使用,::如下所示:

duck culprit = duck::huey; // or "auto culprit" to avoid redundancy

请注意,该::运算符也适用于 C++03 无范围枚举,因此即使第一行丢失,上面的第二行也可以工作class

这可能是过多的细节,但如果向前声明枚举类型,class则不会进入详细类型说明符,如

void quack( enum duck whom ); // not "enum class"

但是,C++11 中有一个新结构opaque-enum-declaration,它确实包含class关键字并定义了一个完整的类型。

enum duck; // duck is declared as incomplete type
enum class duck; // duck is now complete type; underlying type defaults to int

关键字struct可以被替换class,没有语义差异。

于 2012-12-26T14:39:05.197 回答
0
  1. 当数据大小很重要时(可能将其打包在结构中),您可以显式指定存储类型。
  2. 枚举值仅在枚举名称范围;在 c++11 之前,它们会泄漏到封闭范围内。
  3. 我似乎记得转换规则也有所改变......

关于点 1,enums 的存储大小将在 C++11 之前根据分配给枚举的最大值而改变。通常它并不重要,但是当它发生时,你必须诉诸丑陋的黑客来强制大小。

至于第3点,在 C++11enum中 s 不可隐式转换或与ints 或其他enum类型相比较:对于避免函数重载头痛和其他隐式转换陷阱很有用。

于 2012-12-26T14:19:28.430 回答
0

就我个人而言,我在基于 tcp 的消息传递协议中使用了它:许多字段都是枚举值,我只需要在一个字节内进行编码,以尊重消息传递接口。

我所有的枚举都是这样定义的:

enum class EnumFieldA : unsigned char { eValProperty1, eValProperty2};
enum class EnumFieldB : unsigned char { eValProperty1, eValProperty2, eValProperty3};
enum class EnumFieldC : unsigned char { eValProperty1, eValProperty2, eValProperty3, eValProperty4};
...

在这个 SO question中也有很多彻底的答案。

于 2012-12-26T14:21:20.237 回答
-1

起初我对你的问题感到困惑,但我想你想知道 c++ 枚举和 c++11 中的枚举之间的区别。据我所知,在后面,你有强类型的枚举,可以让你确定它们的范围。我认为很好地解释了它。干杯

于 2012-12-26T14:12:24.273 回答