Оператор | = для логического значения в C ++ - PullRequest
11 голосов
/ 26 января 2012

Я наткнулся на следующую конструкцию в C ++:

bool result = false;
for(int i = 0; i<n; i++){
  result |= TryAndDoSomething(i);
}

Я предположил, что это |= было сокращением для оператора ИЛИ, и что result будет равно true в конце, еслипо крайней мере один из этих вызовов TryAndDoSomething возвратил true.

Но теперь мне интересно, может ли более одного вызова на самом деле вернуть true.Действительно, если мы расширим операцию как:

result = result || TryAndDoSomething(i);

Тогда метод будет вызван, только если return оценивается как false, то есть, если никакой другой вызов до этого не был возвращен true.Таким образом, после одного вызова, возвращающего true, никакого другого вызова не будет.

Это правильная интерпретация?

Ответы [ 4 ]

30 голосов
/ 26 января 2012

Это побитовое ИЛИ назначение, не короткое замыкание ИЛИ оценка.

Это эквивалентно:

result = result | TryAndDoSomething(i);

Не:

result = result || TryAndDoSomething(i);
11 голосов
/ 26 января 2012

В логических значениях | дает тот же результат, что и ||, но не закорачивает.Правый операнд |= всегда оценивается.

4 голосов
/ 26 января 2012

Единственная разница в этом контексте между x |= f() (побитовое ИЛИ) и x = x || f() (логическое ИЛИ) заключается в том, что последний имеет короткое замыкание.В первом случае f() будет выполняться n раз - если, конечно, f() не выдаст исключение, но это уже другая история.

В версии ||, f() больше не будетвызываемый один раз x становится true.В C ++ нет оператора ||=, но важно понимать, что из-за этого |= и ||= (если бы они существовали) имели бы другую семантику.|= - это не просто замена отсутствующего ||=.

В качестве примечания, при условии, что вы используете bool, побитовая операция безопасна , потому что стандарт определяетtrue и false преобразуются в целые числа 1 и 0 соответственно.Таким образом, единственное отличие в этом случае состоит в том, что нужно стремиться, а не лениться.

0 голосов
/ 26 января 2012

result |= Try() - это сокращение от result = result | Try();.Вы, похоже, понимаете оператор ||, но оператор | совершенно другой.Это имя побитовое или (в отличие от логического или).Он имеет такой же эффект, как если бы он выполнял a=a||b для каждого бита операндов, и не имеет функции быстрого восстановления, которая логична и / или имеет.(Это также сумасшедший быстрый; такой же быстрый или быстрый, чем сложение).Другие побитовые операции: & (поразрядно и: a=a&&b для каждого бита) и ^ (поразрядно по xor: a=(a!=b) для каждого бита).

...