提问人:sbi 提问时间:12/26/2012 最后编辑:Daniel Heilpersbi 更新时间:7/5/2017 访问量:3704
什么是枚举类,我为什么要关心?
What's an enum class and why should I care?
答:
起初我对你的问题感到困惑,但我想你想知道 c++ 枚举和 c++11 中的枚举之间的区别。据我所知,在后面,你有强类型枚举,允许你确定它们的范围。我认为这很好地解释了它。干杯
评论
- 当数据大小很重要时,您可以显式指定存储类型(也许将其打包在结构中)。
- 枚举值的范围仅限于枚举的名称;在 C++11 之前,它们泄漏到封闭作用域中。
- 我似乎记得转换规则也发生了一些变化......
关于点 1,s 的存储大小将在 C++11 之前更改,具体取决于分配给枚举的最大值。通常这并不重要,但是当它发生时,您必须求助于丑陋的黑客来强制调整大小。enum
至于第 3 点,在 C++11 中,s 不能隐式转换或与 s 或其他类型类似:对于避免函数重载头痛和其他隐式转换陷阱很有用。enum
int
enum
评论
:)
enum class
与使用 指定基础类型无关。:
enum class
enum
int
enum
就个人而言,我在基于 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 问题中也有很多详尽的答案。
评论
enum
class
与指定无关,并且您不应该通过传输结构的字节进行序列化,尤其是在 TCP 上(尽管如果所有字段都是一个字节,这确实避免了字节序问题)。unsigned char
enum class
称为作用域枚举。它可以防止使用枚举器名称污染枚举出现的命名空间。
在 C++03 中,你可以通过将 内部的 .也许这就是语法的来源,这有点令人困惑。enum
class
另一个区别是,此类类型的枚举器不会隐式转换为 ( 是必需的)。这可能很少需要,但它可以安全地重载一个函数,该函数采用一个接受类型的参数。您可以确定不会意外调用。或者,您可以使用专用函数定义伪整型,并确保内置运算符不会干扰。int
static_cast<int>
int
enum
int
operator
这两个不相关的差异出现在同一个包中,并且您无法获得没有隐式转换的无作用域枚举,这有点烦人,但通常这两种更改都是好事,并且是 C++11 中的良好默认做法。enum class
编辑:作用域内枚举的定义如下:
enum class duck { huey, dewey, louie };
并且必须与范围解析运算符一起使用,如下所示:::
duck culprit = duck::huey; // or "auto culprit" to avoid redundancy
请注意,该运算符也适用于 C++03 无作用域枚举,因此即使缺少第一行,上面的第二行也有效。::
class
这可能是过多的细节,但如果正向声明枚举类型,则不会进入 elaborated-type-specifier,如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
评论
+1
class
enum
:)
)
enum E { V }; E e = E::V;
::
上一个:访客模式(如果节点类型非常多)
评论