Побитовый или ( | ) в аргументе функции

мне было интересно, как это сделать:

func(param1|param2|param3)

а затем извлеките эти значения в функции, я видел это в нескольких функциях, или лучше сделать это:

func(param1, ...)

?

Я пытаюсь сделать это на C++, и я думал о том, чтобы иметь параметры функции как значения в перечислении.

Как я могу это решить?

3 ответов


Param1, param2, param3 обычно определяются как числа с различными включенными битами. | является оператором побитовой альтернативы, что означает, что он работает на отдельных битах.

пример:

const int param1 = 0x01;
const int param2 = 0x02;
const int param3 = 0x04;

когда вы передаете аргумент функции, вы делаете побитовую альтернативу ранее определенных параметров. В функции вы не делаете декомпозицию, но проверяете, установлен ли указанный бит, используя побитовое соединение:

void func(int arg){
  if(arg & param1)
    // do something
  if(arg & param2)
    // do something else
    // ...
}

func(param1 | param3); 
// "do something" will be done,
// but "do something else" not.

предполагая, что у вас есть значения как независимые биты (степени двух), такие как:

#define IS_ON    0x01
#define IS_LARGE 0x02
#define IS_RED   0x04

(эквивалент enums или const int значения, в зависимости от того, как вы хотите их делать - я использовал #define просто потому, что это то, к чему я привык), вы можете передать них:

funcname (IS_ON | IS_RED);   // passes in 0x05

затем экстракт их с чем-то вроде:

void funcname (int bitmask) {
    if ((bitmask & IS_ON) == IS_ON) { // 0x05 & 0x01 -> 0x01
        // IS_ON bit is set.
    }
    :
}

для однобитовых спецификаторов вы можете уйти с if (bitmask & IS_ON) форме, но вам нужно полное проверьте, могут ли ваши спецификаторы быть многоразрядными значениями (например, трехразрядный уровень громкости от 0 до 7).


это полезный пример того, как создать функцию "MessageBox" с произвольными типами кнопок:

enum Button
{
    OK =      0x0001,
    CANCEL =  0x0010,
    YES =     0x0100,
    NO =      0x1000
};

void messagebox(char *text, int button)
{
    char msg[256];
    strcpy(msg, text);

    if ((button & Button::OK) == Button::OK)
        strcat(msg, " [OK]");
    if ((button & Button::CANCEL) == Button::CANCEL)
        strcat(msg, " [Cancel]");
    if ((button & Button::YES) == Button::YES)
        strcat(msg, " [Yes]");
    if ((button & Button::NO) == Button::NO)
        strcat(msg, " [No]");

    cout << msg << endl;
}

int main()
{
    messagebox("salam", Button::OK | Button::CANCEL);
    return 0;
}