C ++: логическое сравнение как условный оператор? - PullRequest
5 голосов
/ 29 сентября 2011

Наткнулся на какой-то код, который использовал это, что заставило меня задуматься.

if(condition) foo = bar();

condition && (foo = bar());

Эти два сегмента кода равны компилятору? Если нет, то чем они будут отличаться?

Ответы [ 6 ]

6 голосов
/ 29 сентября 2011

Из-за приоритета оператора последний интерпретируется как:

(condition && foo) = bar();

Кроме того, существует вероятность перегрузки &&, что может привести к чему угодно.

Итак, вкратце: они вовсе не равны - по крайней мере, в общем случае.

2 голосов
/ 29 сентября 2011

Первая версия - это просто старое утверждение.

Вторая версия - это выражение, которое будет возвращать результат всего выражения. Это, вероятно, допускает некоторый хитрый однострочный синтаксис, который, как обычно, потенциально может сделать код более читабельным, но, скорее всего, сделает его более сложным и сложным для быстрого анализа из-за незнакомости.

ИМО либо постоянно использует его везде, чтобы читатели вашего кода привыкли к нему, либо не использует его вообще.

1 голос
/ 29 сентября 2011

Если && не перегружен для комбинации типов condition и foo, они будут вести себя одинаково - последний будет работать следующим образом:

bool result;
if( !condition ) {
     result = false;
} else {
     foo = bar();
     result = foo != 0;
}
and result gets ignored

это обычное короткое замыкание - если первый компонент && равен false, второй не оценивается.

ИМО второй вариант гораздо менее читабелен.

1 голос
/ 29 сентября 2011

Если condition && foo не соответствует lvalue , condition && foo = bar(); не имеет смысла.

0 голосов
/ 29 сентября 2011

Если && не перегружено ни для условия, ни для foo:

condition && (foo = bar());

будет рассматриваться как

(condition.operator bool()) && (foo = bar());

если (условие.operator bool ()) не истинно, (foo = bar ()) не будет выполнено, и наоборот.

0 голосов
/ 29 сентября 2011

Произошла ошибка компилятора: неверное значение l. Чтобы иметь такую ​​же функциональность, вы должны использовать

conticion ? foo = bar( ) : <other accion>;
...