C++使用位移分配枚举显式值

mdo*_*844 4 c++ enums openscenegraph

我一直在研究开源项目中的一些代码,并注意到在不止一个场合,枚举值是通过将一个值转换为增量位数来分配的.我没有看到任何具体的理由这样做,也没有看到通过增加+1来分配值的效率提高.

无论如何,没有一些代码可以证明什么让我感到困惑,这可能没什么意义.

1级

enum EventType {
        NONE                = 0,
        PUSH                = 1<<0,
        RELEASE             = 1<<1,
        DOUBLECLICK         = 1<<2,
        DRAG                = 1<<3,
        MOVE                = 1<<4,
        KEYDOWN             = 1<<5,
        KEYUP               = 1<<6,
        FRAME               = 1<<7,
        RESIZE              = 1<<8,
        SCROLL              = 1<<9,
        PEN_PRESSURE        = 1<<10,
        PEN_ORIENTATION     = 1<<11,
        PEN_PROXIMITY_ENTER = 1<<12,
        PEN_PROXIMITY_LEAVE = 1<<13,
        CLOSE_WINDOW        = 1<<14,
        QUIT_APPLICATION    = 1<<15,
        USER                = 1<<16
    };
Run Code Online (Sandbox Code Playgroud)

2级

    enum EventType {
        EVENT_MOUSE_DOUBLE_CLICK = osgGA::GUIEventAdapter::DOUBLECLICK,
        EVENT_MOUSE_DRAG         = osgGA::GUIEventAdapter::DRAG,
        EVENT_KEY_DOWN           = osgGA::GUIEventAdapter::KEYDOWN,
        EVENT_SCROLL             = osgGA::GUIEventAdapter::SCROLL,
        EVENT_MOUSE_CLICK        = osgGA::GUIEventAdapter::USER << 1,
        EVENT_MULTI_DRAG         = osgGA::GUIEventAdapter::USER << 2,   // drag with 2 fingers
        EVENT_MULTI_PINCH        = osgGA::GUIEventAdapter::USER << 3,   // pinch with 2 fingers
        EVENT_MULTI_TWIST        = osgGA::GUIEventAdapter::USER << 4    // drag 2 fingers in different directions
    };
Run Code Online (Sandbox Code Playgroud)

如果我正确读取此事件,则EventType :: USER的二进制文件的显式值为65536或10000000000000000.EVENT_MULTI_TWIST的二进制值为1048576或100000000000000000000.

以这种方式分配枚举值的目的是什么?

enum EventType {
        NONE                = 0,
        PUSH                = 1,
        RELEASE             = 2,
        DOUBLECLICK         = 3,
        DRAG                = 4,
        MOVE                = 5,
        KEYDOWN             = 6,
        KEYUP               = 7,
        FRAME               = 8,
        RESIZE              = 9,
        SCROLL              = 10,
        PEN_PRESSURE        = 11,
        PEN_ORIENTATION     = 12,
        PEN_PROXIMITY_ENTER = 13,
        PEN_PROXIMITY_LEAVE = 14,
        CLOSE_WINDOW        = 15,
        QUIT_APPLICATION    = 16,
        USER                = 17
    };
Run Code Online (Sandbox Code Playgroud)

Jer*_*fin 9

这样做的通常原因是将每个枚举值与最终v值的单个位相关联,因此您可以(例如)将多个标志编码为单个变量.

例如,对于典型的32位系统,您可以(显然足够)将32个单独的标志编码为单个32位int(或者,最好是unsigned int).

例如,如果你正在寻找在键盘上的键,你可以编码"正常"键,如字母和数字为一个字节(可能使用连续的值,如你所建议的),而像"修饰"键shift,altcontrol作为个别位.这将允许您(例如)将类似control+ alt+的内容编码A为单个值.

同样,对于鼠标消息,您可以将鼠标按钮视为"修饰符",因此您可以将鼠标拖动为单个值.

在这两种情况下,将"修饰符"编码为单个位的重要一点是,这允许您稍后无误地检索这些修饰符 - 如果在值中设置了正确的位,则使用该修饰符.相比之下,如果您只使用连续数字,则之后无法提取单个部分.例如,如果你有编码作为输入1,2并且3,可以不告诉是否3旨在指示对应于原始输入3或两者的输入端12在同一时间.但是,如果将值编码为1,2并且4,您可以组合值,并仍然对它们进行解码,这样您就可以准确地看到生成特定值所需的输入.