这与Are C++ enums signed or unsigned?密切相关。根据JavaMan的回答,enum
既不是signed
也不是unsigned
。但它确实遵循整体推广规则。
我正在使用使用enums
的库,然后将它们传递给其他大多数unsigned
类型的类对象(例如unsigned int
和size_t
)。为了捕获合法错误而启用-Wsign-conversion
警告会因语言规则而导致一些误报。
规则类型创造了一种难以确保类型安全并捕捉常见错误的情况。这很困难,因为我想避免像static_cast
这样的事情在整个代码中大量涌现。
是否有办法覆盖语言的默认行为,以便将enums
提升为具体的signed
或unsigned
类型? (类似于您指定char
已签名或未签名的方式)。
相关的,该库是在20世纪90年代编写的,因此它支持许多较旧的编译器。如果解决方案甚至可以解决C ++ 03以及可能更早的问题,那将会很棒。
从How to guard move constructors for C++03 and C++11?开始,我知道在实践中没有可靠的方法来检测其他C ++语言变体何时生效。在使用-std=c++03
和-std=c++11
进行Clang 3.5测试时,它的表面平平。
答案 0 :(得分:2)
C ++ 03枚举的基础类型取决于其枚举器的值范围,并且它会升级到其基础类型,而不是int
(C ++ 98 [conv.prom]§4.5/ 2)。
强制枚举表现为unsigned int
的肮脏方法是添加只有unsigned int
可以处理的值。
enum things {
a, b, c,
force_unsigned = -1U
};
答案 1 :(得分:1)
您可以推送自己的enum class
:
struct safe_enum {
enum type {
value1, value2, value3
};
type value;
operator unsigned int ()
{ return value; }
};
safe_enum foo = safe_enum::value1;
unsigned bar = safe_enum::value2;
不幸的是,这会丢失C ++ 03枚举的“无范围”行为,因此这种最佳实践模式将破坏代码库。此外,将enum
更改为class
会破坏ABI(如果已将其作为DLL发送)。