如何覆盖枚举的积分提升规则
How to override integral promotion rule for enum?
这与C++枚举是有符号的还是无符号的密切相关?。根据JavaMan的回答,enum
既不是signed
也不是unsigned
。但它确实遵循了整体晋升规则。
我正在使用一个库,该库使用enums
,然后将它们传递给其他主要期望unsigned
类型的类对象(如unsigned int
和size_t
(。由于语言的规则,启用-Wsign-conversion
警告以捕捉合法错误会导致大量误报。
该规则造成了一种难以确保类型安全和发现常见错误的情况。这很困难,因为我想避免像static_cast
这样的东西在整个代码中随意地散布。
是否有一种方法可以覆盖将enums
提升为具体signed
或unsigned
类型的语言默认行为?(类似于指定char
有符号或无符号的方式(。
相关的,该库是在20世纪90年代编写的,因此它支持许多较旧的编译器。如果该解决方案甚至能解决C++03问题,甚至可能更早,那就太好了。
从如何保护C++03和C++11的移动构造函数?,我知道在实践中没有可靠的方法来检测其他C++语言变体何时生效。在使用-std=c++03
和-std=c++11
的Clang 3.5测试过程中,它的脸平掉了。
C++03枚举的底层类型取决于其枚举器的值范围,并且它提升为其底层类型,而不是int
(C++98[conf.prom]§4.5/2(。
强制枚举表现为unsigned int
的肮脏方法是添加一个只有unsigned int
才能处理的值。
enum things {
a, b, c,
force_unsigned = -1U
};
演示:http://coliru.stacked-crooked.com/a/d3ded108fb5a68bf
您可以滚动自己的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提供(。
- 不带大括号的枚举形式
- 枚举环境变量的惯用C++14/C++17方法
- 类似枚举的计算常量
- 如何正确实现和访问运算符的各种自定义枚举器
- 错误:从"int"到枚举c++的转换无效
- C++中构造函数中的枚举
- 访问在 C++ 结构中声明的枚举变量
- 枚举类'classname'的多重定义
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- typedef 枚举和枚举类有什么区别?
- 为什么我的开关/机箱在使用枚举时默认?
- 标准::可选枚举的比较运算符
- C++两个源文件之间共享的枚举的静态实例
- 打印没有铸件的枚举可以在C++中吗?
- 枚举成员与静态 int 成员?
- C++:枚举:错误:应使用标识符而不是"}"
- 带有 c++ 的枚举(输入检查)
- 在 qml 中使用 Q_ENUM 和 Q_PROPERTY 作为枚举类
- 应用有关如何递增枚举的规则
- 如何覆盖枚举的积分提升规则