我一直在尝试阅读一些C++标准,以了解枚举是如何工作的。实际上,它比我原先想象的要多。
对于限定了作用域的枚举,除非使用enum-base子句指定(它可以是任何整型),否则很明显底层类型是int。
enum class color { red, green, blue}; // these are int对于无作用域枚举,基础类型似乎可以是任何可以工作的整数类型,并且它不会大于int,除非需要这样做。
enum color { red, green, blue}; // underlying type may vary由于未限定作用域的枚举的底层类型没有标准化,那么处理其中的序列化实例的最佳方法是什么?到目前为止,我一直在编写时转换为int,然后将其序列化为int,并在读取时将enum变量设置在开关中,但这似乎有些笨拙。有没有更好的方法?
enum color { red, green, blue };
color c = red;
// to serialize
archive << (int)c;
// to deserialize
int i;
archive >> i;
switch(i) {
case 0: c = red; break;
case 1: c = green; break;
case 2: c = blue; break;
}发布于 2009-05-12 16:23:25
我还没有读过任何C++0x的东西,所以我不能对此发表评论。
至于序列化,在读回枚举时不需要开关-只需将其转换为枚举类型即可。
但是,在写入到流时,我不进行强制转换。这是因为我经常喜欢为枚举编写一个operator<<,这样我就可以捕获正在写入的坏值,或者我可以决定写出一个字符串。
enum color { red, green, blue };
color c = red;
// to serialize
archive << c; // Removed cast
// to deserialize
int i;
archive >> i;
c = (color)i; // Removed switch发布于 2009-05-12 15:32:27
枚举类是一个C++0x功能,它不存在于C++03中。
在标准C++中,枚举不是类型安全的。它们实际上是整数,即使枚举类型是不同的。这允许在不同枚举类型的两个枚举值之间进行比较。C++03提供的唯一安全性是一种枚举类型的整数或值不会隐式转换为另一种枚举类型。此外,不能显式指定基础整数类型,即整数的大小;它是由实现定义的。最后,枚举值的作用域为封闭作用域。因此,两个单独的枚举不可能具有匹配的成员名称。C++0x将允许对没有这些问题的枚举进行特殊分类。这是使用枚举类声明来表示的
示例(来自wikipedia文章):
enum Enum1; //Illegal in C++ and C++0x; no size is explicitly specified.
enum Enum2 : unsigned int; //Legal in C++0x.
enum class Enum3; //Legal in C++0x, because enum class declarations have a default type of "int".
enum class Enum4: unsigned int; //Legal C++0x.
enum Enum2 : unsigned short; //Illegal in C++0x, because Enum2 was previously declared with a different type.至于序列化部分(我认为这不是原始问题的一部分),我更喜欢创建一个帮助器类,将枚举项转换为它们的字符串等效项(来回转换),因为名称通常比它们表示的整数值更稳定,因为枚举项可以(有时也是)重新排序,而不会更改代码行为。
发布于 2009-05-12 17:04:01
我决定创建一个新的答案,因为我的旧答案太乱了。无论如何,我只想说一些关于C++11的事情,你可以使用下面这个来获取枚举的底层类型:
std::underlying_type_t<E>出于兴趣考虑,重载解决方案的想法。但请按照@lothar的建议使用名称来存储枚举。
重载解析源于这样一个事实,即存在一个从枚举到int、unsigned int、long、unsigned long的第一个可以表示其基础类型的所有值的提升。转换为任何其他整数类型的级别较低,并且重载解析不会首选它。
char (& f(int) )[1];
char (& f(unsigned int) )[2];
char (& f(long) )[3];
char (& f(unsigned long) )[4];
char const* names[] = {
"int", "unsigned int",
"long", "unsigned long"
};
enum a { A = INT_MIN };
enum b { B = UINT_MAX };
enum c { C = LONG_MIN };
enum d { D = ULONG_MAX };
template<typename T> void print_underlying() {
std::cout << names[sizeof(f(T()))-1] << std::endl;
}
int main() {
print_underlying<a>();
print_underlying<b>();
print_underlying<c>();
print_underlying<d>();
}它会在这里打印以下内容:
int
unsigned int
int
unsigned int它对这个序列化问题没有特别的意义(因为序列化的数据的大小不是恒定的宽度,当枚举及其底层类型改变时,这可能会导致问题),但是找出一个存储整个枚举的类型通常很有趣。干杯!
https://stackoverflow.com/questions/853368
复制相似问题