我正在使用C ++中的自定义枚举类型,但它没有很多值。我想尝试减少他们占用的大小,我听说enum
类型是always integers by default。然后我遇到了MSDN entry on C++ enumerations,发现以下语法非常有趣:
enum [: type] {enum-list};
果然,当我做了以下事情时,它编译了我想要的东西(VS2008):
enum plane : unsigned char { xy, xz, yz };
现在,你可以从我的枚举常量中看到我在空间方面不需要太多 - 一个unsigned char类型对我的用途来说是完美的。
但是,我不得不说,我从来没有看到过这种形式在互联网上的任何地方使用其他地方 - 大多数人甚至都没有意识到这一点。我试图让这个代码跨平台(并且可能用于嵌入式系统),所以它让我想知道......这是正确的C ++语法,还是只有MSVC编译器支持?
编辑:此功能现在似乎是C ++ 11及更高版本的一部分,名为scoped enumerations。
答案 0 :(得分:7)
这是非标准的,但预计它将成为C ++ 0x标准的一部分。对我来说,当我在Visual Studio 2005中编译并将警告级别设置为最大值时,我收到以下警告:
警告C4480:使用非标准扩展名:为枚举“测试”指定基础类型
在标准C ++中,枚举不是类型安全的。他们是有效的 整数,即使枚举类型不同。这允许 不同枚举类型的两个枚举值之间的比较。 C ++ 03提供的唯一安全性是整数或值 一个枚举类型不会隐式转换为另一个枚举类型。 另外,底层整数类型是实现定义的; 因此,依赖于枚举大小的代码 非便携。最后,枚举值的范围限定为封闭 范围。因此,两个单独的枚举不可能具有 匹配成员名称。
此外, C ++ 0x 将允许提供标准枚举 显式范围以及基础类型的定义:
enum Enum3 : unsigned long {Val1 = 1, Val2};
答案 1 :(得分:2)
正如0A0D所说,你所使用的符号在C ++ 03中是非标准的,但在“scoped enums”一词中被C ++ 11采用。
如果这对您来说还不够快,那么您可以考虑明确指定用于嵌入它们的大小关键结构中的枚举字段的位字段宽度。这种方法很难看 - 我提到是否完整;如果这是一个很好的解决方案,上面的符号将不会被C ++ 11采用。一个问题是您依赖于可选的编译器警告来检测太小的位字段以保存可能的值,并且可能必须在枚举值更改时手动查看它们。
例如:
enum E
{
A, B, C
};
struct X
{
E e1 : 2;
E e2 : 2;
E e3 : 2;
E e4 : 2;
};
注意:枚举可能占用比请求更多的位 - 在GCC 4.5.2上没有明确的编译器选项,上面的sizeof(X)
仍然是4 ....
答案 2 :(得分:0)
这完全合法。然而,如果没有专门确保对齐,则将类型嵌入到对象中以节省空间将是无效的。如果保留默认对齐,则通常将填充字节(取决于体系结构)添加到四字边界。