如何覆盖枚举的整数提升规则?

时间:2015-07-06 06:45:04

标签: c++ enums integer-promotion

这与Are C++ enums signed or unsigned?密切相关。根据JavaMan的回答,enum既不是signed也不是unsigned。但它确实遵循整体推广规则。

我正在使用使用enums的库,然后将它们传递给其他大多数unsigned类型的类对象(例如unsigned intsize_t)。为了捕获合法错误而启用-Wsign-conversion警告会因语言规则而导致一些误报。

规则类型创造了一种难以确保类型安全并捕捉常见错误的情况。这很困难,因为我想避免像static_cast这样的事情在整个代码中大量涌现。

是否有办法覆盖语言的默认行为,以便将enums提升为具体的signedunsigned类型? (类似于您指定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测试时,它的表面平平。

2 个答案:

答案 0 :(得分:2)

C ++ 03枚举的基础类型取决于其枚举器的值范围,并且它会升级到其基础类型,而不是int(C ++ 98 [conv.prom]§4.5/ 2)。

强制枚举表现为unsigned int的肮脏方法是添加只有unsigned int可以处理的值。

enum things {
    a, b, c,
    force_unsigned = -1U
};

演示:http://coliru.stacked-crooked.com/a/d3ded108fb5a68bf

答案 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发送)。