Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用对另一个枚举值的操作定义枚举元素值_C++_C++11_Enums_Constexpr_Enum Class - Fatal编程技术网

C++ 使用对另一个枚举值的操作定义枚举元素值

C++ 使用对另一个枚举值的操作定义枚举元素值,c++,c++11,enums,constexpr,enum-class,C++,C++11,Enums,Constexpr,Enum Class,我需要做的是:在一个类中定义两个枚举,第二个枚举使用第一个枚举中的元素值定义元素 比如说: 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,

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

比如说:

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
};
#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 )
...
但我得到了以下错误:

错误:静态constexpr unsigned int 在常量中调用merge(std::initializer\u list) 表情

我从中了解到,
merge
方法只有在类被完全声明后才被认为是声明的和可用的

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

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
};
#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 )
...
#定义合并元素(a,b)静态|强制转换(a)|静态|强制转换(b)
#定义合并3个元素(a、b、c)静态转换(a)|合并2个元素(b、c)
#定义合并4个元素(a、b、c、d)静态转换(a)|合并3个元素(b、c、d)
#定义合并5个元素(a、b、c、d、e)静态_cast(a)|合并4个元素(b、c、d、e)
...
但我需要能够合并多达20个
Elem
s,这样编写20个宏似乎不是一个合适的解决方案


这里的方法是什么?

铸造
Elem
enum的值怎么样

        first = int(Elem::A) | int(Elem::B),
        second = int(Elem::A) | int(Elem::C),

您需要对枚举数对应的整数类型进行静态强制转换,以便内置
运算符|

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)
    };
};
class-MyClass
{
public:enum类元素:unsigned int
{
A=1,B=2,C=4,D=8
};
public:enum类组:unsigned int
{
第一个=静态_转换(元素A)|静态_转换(元素B)
,second=static_cast(Elem::A)| static_cast(Elem::C)
};
};

您可以按照定义的顺序进行操作:

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,

};
class-MyClass{
公众:
枚举类元素{A=1,B=2,C=4,D=8};
枚举类组;
};
constexpr MyClass::Elem运算符|(
常量MyClass::Elem&l,常量MyClass::Elem&r){
返回静态输出(
静态铸造(l)|静态铸造(r)
);
}
枚举类MyClass::组{
第一=元素A |元素B,
第二个=元素A |元素C,
};


但整个想法都与类型安全枚举的概念背道而驰。也许你可以用那些好的不安全的旧方法?

:(我真的认为这和我的
merge
方法一样有效。)看起来有点可笑。所有需要的类都已完全声明:(这是如何“违背类型安全枚举的概念的”?好吧,你在这里施压放弃了一点类型安全。我的直觉告诉我,这可能不是你最不想施压的地方。胡乱猜测,但是第二天,或者在某个时候,你会想检查是否设置了一个或` ed标志,对吗?来了,然后你想把它传递给C API,并实现一个conv版本。这样一来,你无论如何都会一点一点地放弃它,最终会遇到一个混乱的“C+”黑客。但是你更了解你的项目和你的纪律感,所以最终由你来决定。