3

这是我需要做的:在一个类中定义两个枚举,第二个具有使用第一个元素值定义的元素。

所以是这样的:

class MyClass
{
    public:
        enum class Elem {
            A=1, B=2, C=4, D=8
        };
        enum class Group {
            first = Elem::A | Elem::B,
            second = Elem::A | Elem::C,
            //...
        }; <-- compilation error
};

但是,由于默认情况下未为es定义,因此无法编译。|enum class

我试图在类之外(在类主体之后)为枚举定义|运算符,但是在定义枚举时该运算符是未知的。ElemMyClassGroup

所以我然后尝试了以下方法,即在类中定义一个constexpr函数:

class MyClass
{
    public:
        enum class Elem {
            A=1, B=2, C=4, D=8
        };

        constexpr static unsigned int merge(
            std::initializer_list<MyClass::Elem> list)
        {
            //Test only: should be an '|' on all list elements
            return 1;
        }

        enum class Group {
            first = merge({Elem::A,Elem::B}),
            second = merge({Elem::A,Elem::C}),
            /*...*/
        };
};

但我收到以下错误:

错误:在常量表达式中调用了静态 constexpr unsigned int merge(std::initializer_list list)

我从这里那里了解到,只有在类完全声明后,该merge方法才被视为已声明和可用。

我能想到的最后一个解决方案是使用这样的宏:

#define MERGE2ELEMS( a, b ) static_cast<unsigned int>(a) | static_cast<unsigned int>(b)
#define MERGE3ELEMS( a, b, c ) static_cast<unsigned int>(a) | MERGE2ELEMS( b, c )
#define MERGE4ELEMS( a, b, c, d ) static_cast<unsigned int>(a) | MERGE3ELEMS( b, c, d )
#define MERGE5ELEMS( a, b, c, d, e ) static_cast<unsigned int>(a) | MERGE4ELEMS( b, c, d, e )
...

但是我需要能够合并最多 20Elem秒,并且像这样编写 20 个宏似乎不是一个合适的解决方案。

去这里的方法是什么?

4

3 回答 3

2

您可以使用定义顺序:

class MyClass {
   public:
    enum class Elem { A = 1, B = 2, C = 4, D = 8 };
    enum class Group;
};

constexpr MyClass::Elem operator|(
    const MyClass::Elem& l, const MyClass::Elem& r) {
    return static_cast<MyClass::Elem>(
              static_cast<int>(l) | static_cast<int>(r)
    );
}

enum class MyClass::Group {
    first = Elem::A | Elem::B,
    second = Elem::A | Elem::C,

};

现场演示

但是整个想法有点违背类型安全枚举的概念。也许你可以只使用旧的不安全的好东西?

于 2017-10-04T21:32:51.430 回答
1

您需要对与 enumerator 对应的整数类型进行静态转换,以便内置operator |

class MyClass
{
    public: enum class Elem: unsigned int
    {
        A=1, B=2, C=4, D=8
    };
    public: enum class Group: unsigned int
    {
        first  = static_cast<unsigned int>(Elem::A) | static_cast<unsigned int>(Elem::B)
    ,   second = static_cast<unsigned int>(Elem::A) | static_cast<unsigned int>(Elem::C)
    };
};
于 2017-10-04T21:29:38.467 回答
1

投射Elem枚举的值怎么样?

        first = int(Elem::A) | int(Elem::B),
        second = int(Elem::A) | int(Elem::C),
于 2017-10-04T21:26:49.310 回答