以下是我需要做的事情:在类中定义两个枚举,第二个使用第一个元素值定义元素。
这样的事情:
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
};
但是, 这不会编译 ,因为默认情况下|
未定义enum class
。
我尝试在|
类之外(在类主体之后)定义Elem
枚举的MyClass
运算符,但是在Group
之后不知道运算符{枚举{1}}枚举。
所以我接着尝试了以下内容,即在课程中定义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}),
/*...*/
};
};
但是我收到以下错误:
错误:static constexpr unsigned int merge(std :: initializer_list list)在常量中调用 表达
我从here和there了解到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 )
...
但是我需要能够合并多达20个Elem
并编写20个这样的宏似乎不是一个合适的解决方案。
去这里的方式是什么?
答案 0 :(得分: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,
};
但整个想法有点违背了类型安全枚举的概念。也许你可以使用旧的不安全的那些?
答案 1 :(得分:1)
如何投射Elem
枚号的值?
first = int(Elem::A) | int(Elem::B),
second = int(Elem::A) | int(Elem::C),
答案 2 :(得分:1)
您需要对枚举器对应的整数类型进行静态强制转换,以便内置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)
};
};