C ++范围的枚举,可以隐式转换为整数

时间:2017-09-25 14:18:14

标签: c++ enums

我对enumenum class的不同形式有疑问,特别是指定了大量(作用域!)常量。

我想知道是否有办法将范围的枚举声明为隐式转换为整数。用于此的用例是指定寄存器地址,并能够使用MY_REGISTERS::FOO之类的内容访问它们。

以下是我所知道和遇到的选项,请设想一个签名为void do_something(uint32_t bla)的函数。

1:enum class

Enum类具有作用域,但不能隐式转换为整数。我觉得重要的是我没有static_cast它到一个整数,所以这看起来不合适。

enum class Foo : uint32_t
{
    BAR = 0x0000,
    BAZ = 0x0001
};

do_something(Foo::BAR) // Illegal, I'd have to `static_cast` here

2:enum

常规的C样式枚举可以隐式转换为整数,但不是作用域(并污染它所在的命名空间)。这是一个为什么我发现这对我的用例不合适的例子:

enum Foo : uint32_t
{
    BAR = 0x0000,
    BAZ = 0x0001
}

do_something(Foo::BAR) // Legal, and what I am looking for
do_something(BAR)      // Legal, whilst I don't want this to be possible

3:namespaced enum

这很有效,但如果我在某个地方遇到这个问题,我会挑起眉毛。有些东西告诉我可能有更好的方法

namespace Foo
{
    enum dontcare : uint32_t
    {
        BAR = 0x0000,
        BAZ = 0x0001
    };
}

do_something(Foo::BAR) // Legal, and what I am looking for
do_something(BAR)      // Illegal, just like I want it to be

4:namespaced static constexpr

虽然这样做符合我的要求,但我再次(就像命名空间enum一样)觉得必须有更好的方法。

namespace Foo
{
    static constexpr uint32_t BAR = 0x0000,
    static constexpr uint32_t BAZ = 0x0001
}

do_something(Foo::BAR) // Legal, and what I am looking for
do_something(BAR)      // Illegal, just like I want it to be

所以,总而言之,是否有更好的方法,或者我必须坚持命名空间enum s或命名空间constexpr

1 个答案:

答案 0 :(得分:2)

你可以通过将struct与嵌套的匿名枚举混合来破解你自己的范围枚举(编辑:我想enum本身不会 是匿名的):

struct Foo{
    enum: uint32_t
    {
        BAR = 0x0000,
        BAZ = 0x0001
    };
};

Live Demo

根据C ++ 11语义([dcl.enum]),它不是范围的枚举,但它至少是一个限定为Foo类的枚举。它可以像你想要的那样使用而不会污染全局命名空间:

do_something(Foo::BAR);