Побитовый или (|) в аргументе функции - PullRequest
10 голосов
/ 08 января 2012

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

func(param1|param2|param3)

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

func(param1, ...)

?

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

Как мне решить эту проблему?

Ответы [ 3 ]

17 голосов
/ 08 января 2012

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.
13 голосов
/ 08 января 2012

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

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

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

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, например) .

0 голосов
/ 21 июля 2016

Это полезный пример того, как создать функцию «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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...