题
我一直想读一位C ++标准的要弄清楚如何枚举的工作。这事实上有更多比我原来想象。
有关一个范围的枚举,很明显的是,下面的类型是int
除非用枚举基子句另有规定(它可以是任何一体型)。
enum class color { red, green, blue}; // these are int
有关无作用域枚举,它看起来像的基础类型可以是任何类型的积分,将工作,并且它不会比int更大,除非它需要。
enum color { red, green, blue}; // underlying type may vary
由于未范围enumarations的基础类型不规范,什么是处理一个序列化的实例的最佳方法?到目前为止,我已经写转换然后序列化到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;
}
解决方案
我还没有读取的任何的C ++ 0x的东西,所以我不能对此作出评论。
至于序列化,你不读回枚举时需要的开关 - 只是将它转换为枚举类型
不过,我不写入流时施放。这是因为我经常喜欢写操作<<对于枚举,所以我能赶上被写入坏的价值观,或者那我可以决定,而不是写出来的字符串。
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
其他提示
枚举类是一个的C ++ 0x 一>的功能,它不存在于C ++ 03
在标准C ++,枚举不是类型安全的。它们是有效的整数,即使枚举类型是不同的。这允许不同的枚举类型的两个枚举值之间的比较。该C ++ 03提供了唯一的安全是一个整数或一个枚举类型的值不会隐式转换为另一种类型的枚举。此外,底层的整数类型,该整数的大小,不能被明确指定,它是实现定义。最后,枚举值被限定在封闭范围。因此,是不可能的两个单独的枚举到具有匹配的成员名称。 的C ++ 0x将允许枚举的一个特殊的类别有没有这些问题。这是通过使用枚举类声明表达
实施例(从维基百科文章):
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.
对于连载(我认为这是不是原来的问题的一部分),我希望创建一个帮助类转换枚举项目纳入其等效字符串(和背面),作为地名通常比更稳定整数值它们代表,如枚举项可以(有时是)在不改变代码的行为重新排序。
我决定创建一个新的答案,因为我年纪那么杂乱。反正只是想说一些关于C ++ 11,在那里你可以使用获得的基础类型的枚举的这一个:
std::underlying_type_t<E>
和感兴趣的缘故,重载决议的想法。但是,请使用名称来存储枚举建议,由@lothar。
在重载解析来源于这样的事实,有存在一个促进从枚举到所述第一INT,无符号整型,长的,无符号长可表示其基础类型的所有值。 A转换到任何其他整数类型较低等级和过载的分辨率不会喜欢它。
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
这不是特别感兴趣的该序列化问题(因为序列化的数据的大小是不恒定的宽度,并且当所述计数和其底层类型改变这可能会造成问题),但它通常是有趣弄清楚一种类型的存储整个枚举的。干杯!
#include <type_traits>
enum a { bla1, bla2 };
typedef typename std::underlying_type<a>::type underlying_type;
if (std::is_same<underlying_type, int>::value)
std::cout << "It's an int!" << endl;
else if (std::is_same<underlying_type, unsigned int>::value)
std::cout << "It's an uint!" << endl;
至于enum class color
:这是C ++ / CLI(C ++ .NET)或将来的C ++ 0x代码
有关序列化,你可以用sizeof(color)
得到枚举的规模知道有多少要复制的字节。