比较枚举与开关的组合?

时间:2014-07-22 14:12:44

标签: c++ switch-statement

我需要在同一个开关中比较两个枚举值的不同组合,到目前为止我唯一的方法就是嵌套这样的开关:

enum enum1
{
    A,B,C,D,E,F,G,
    H,I,J,K,L,M,N
};

enum enum2
{
    O,P,R,S,T,U,V,
    Z,X,Y
};

enum1 x;
enum2 y;

switch(x)
{
    case A:
        switch(y)
        {
            case O:
                // do stuff
                break;
        }
    case B:
        switch(y)
        {
            case O:
            // do stuff
            break;
        }
     // etc...
}

这种方法使我的交换机真的很长,我试图实现一些不同的方法来减少代码量...... 例如这样的事情不起作用:

int combination = C | P; // combine two enum values (enums from above code)

switch(combination)
{
    case (A | P):
        // do stuff
        break;
    case (B | O): // error: duplicate value
        break;
}

你可以推荐一些关于如何通过不输入太多案例来获得最佳结果的好方法:案例:?

4 个答案:

答案 0 :(得分:1)

开关的问题在于,当计算情况的逐位OR时,相同的值出现多次(例如:A | P与B | O相同),如果没有为其分配值枚举的元素取值为0..n,你可以为枚举的元素分配特定的值,在推荐的情况下,它们是2(1,2,4,8,...)位标志的幂,这可以向你保证,当按位应用OR时,将没有相同的值(枚举的所有元素都有不同的int,这也意味着,总共不能超过32个枚举元素,计算enum1和enum2 )。

第一种情况建议始终以0x1开始分配值(在这种情况下,需要对其中一个枚举进行移位,因为如果不是,则位标志将发生冲突并且可能再次重复值)。宏可以而且应该如果允许C ++ 11被constexpr更改。

第二种情况(推荐)将值分配给已经移位的枚举元素,不需要宏或constexpr。

#include <fstream>
#include <iostream>
#include <vector>

using namespace std;

enum enum1_1 { A = 1, B = 2, C = 4, D = 8 };
enum enum2_1 { O = 1, P = 2, R = 4, S = 8 };

enum enum1_2 { AA = 0x00000001, BB = 0x00000002, CC = 0x00000004, DD = 0x00000008 };
enum enum2_2 { OO = 0x00010000, PP = 0x00020000, RR = 0x00040000, SS = 0x00080000 };

#define COMB(en1, en2) (en1) | (en2 << 16)

int main(int argc, char* argv[]) {
    // Case 1
    enum1_1 x = A;
    enum2_1 y = O;
    int combination1 = COMB(x, y);
    switch (combination1) {
      case COMB(A, O): std::cout << "comb a-o" << std::endl; break;
      case COMB(A, P): std::cout << "comb a-p" << std::endl; break;
      case COMB(A, R): std::cout << "comb a-r" << std::endl; break;
      case COMB(A, S): std::cout << "comb a-s" << std::endl; break;
      case COMB(B, O): std::cout << "comb b-o" << std::endl; break;
      case COMB(B, P): std::cout << "comb b-p" << std::endl; break;
      case COMB(B, R): std::cout << "comb b-r" << std::endl; break;
      case COMB(B, S): std::cout << "comb b-s" << std::endl; break;
    }

    // Case 2
    enum1_2 xx = BB;
    enum2_2 yy = PP;
    int combination2 = xx | yy;
    switch (combination2) {
      case AA | OO: std::cout << "comb a-o" << std::endl; break;
      case AA | PP: std::cout << "comb a-p" << std::endl; break;
      case AA | RR: std::cout << "comb a-r" << std::endl; break;
      case AA | SS: std::cout << "comb a-s" << std::endl; break;
      case BB | OO: std::cout << "comb b-o" << std::endl; break;
      case BB | PP: std::cout << "comb b-p" << std::endl; break;
      case BB | RR: std::cout << "comb b-r" << std::endl; break;
      case BB | SS: std::cout << "comb b-s" << std::endl; break;
    }
    return 0;
}

答案 1 :(得分:0)

使用|的上述方法符号仅在将唯一位值与每个代码关联时才起作用,因为您实际上是对整数位值执行OR运算。定义每个项目时,请尝试将唯一位与每个项目相关联。

例如:

enum enum1 {
   A = 0x00000001,
   B = 0x00000002,
   C = 0x00000004,
   D = 0x00000008,
   E = 0x00000010,
   ...
};

答案 2 :(得分:0)

由于enum1enum2域重叠,因此写入的枚举按位OR'将导致重复值。如果确保enum1enum2中的枚举值不共享任何相同的位,则应该能够使用按位OR技术。

请参阅@ user2835484

答案 3 :(得分:-1)

实际上你可以将多个案例合二为一,正如你在组合示例中指出的那样,但我认为语法应该是这样的:

switch(combination)
{
    case A: case P:
        // do stuff
        break;
    case B: case O: // error: duplicate value
        break;
}