Подтвердить что ты не робот

"IF" аргумент оценки аргумента?

if(a && b)
{
  do something;
}

есть ли возможность оценить аргументы справа налево (b → a)?

если "да", что влияет на порядок оценки?

(я использую VS2008)

4b9b3361

Ответ 1

Порядок оценки задается стандартом и left-to-right. Левое выражение всегда будет сначала оценено с предложением &&.

Если вы хотите сначала оценить b:

if(b && a)
{
  //do something
}

Если оба аргумента являются методами и вы хотите, чтобы оба они были оценены независимо от их результата:

bool rb = b();
bool ra = a();

if ( ra && rb )
{
  //do something
}

Ответ 2

С С++ существует всего несколько операторов, которые гарантируют порядок оценки

  • operator && сначала оценивает левый операнд, и если значение логически false, то оно позволяет избежать оценки правильного операнда. Типичным использованием является, например, if (x > 0 && k/x < limit) ..., что позволяет избежать деления на нулевые проблемы.

  • operator || сначала оценивает левый операнд, и если значение логически true, то оно позволяет избежать оценки правильного операнда. Например, if (overwrite_files || confirm("File existing, overwrite?")) ... не будет запрашивать подтверждение, если установлен флаг overwrite_files.

  • operator , в любом случае оценивает левый операнд, а затем правый операнд, возвращая значение правого операнда. Этот оператор не используется очень часто. Обратите внимание, что запятыми между параметрами в вызове функции являются не операторы запятой, и порядок оценки не гарантируется.

  • Тернарный оператор x?y:z сначала оценивает x, а затем в зависимости от логического значения результата оценивается либо только y, либо только z.

Для всех остальных операторов порядок оценки не указан.

Ситуация на самом деле хуже, потому что это не то, что порядок не указан, но что для выражения вообще нет даже "порядка", и, например, в

std::cout << f() << g() << x(k(), h());

возможно, что функции будут вызываться в порядке h-g-k-x-f (это немного тревожно, потому что ментальная модель оператора << как-то передает идею последовательности, но на самом деле уважает последовательность только в том порядке, в котором поставлены результаты по потоку, а не в порядке, когда результаты вычисляются).

Очевидно, что зависимостей значений в выражении могут вводить некоторую гарантию порядка; например, в приведенном выше выражении он гарантировал, что как k(), так и h() будут вызываться до x(...), потому что для вызова x необходимы значения возврата из обоих.

Обратите также внимание, что гарантии для &&, || и , действительны только для предопределенных операторов. Если вы перегружаете эти операторы для своих типов, они будут в этом случае, как обычные вызовы функций, и порядок оценки операндов будет неуказан.

Ответ 3

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

Если a возвращает false, то b вообще не разрешается оценивать.

Ответ 4

Каждое вычисление значения и побочный эффект первого (левого) аргумента встроенного логического оператора AND && & и встроенный логический оператор OR || секвенируется перед каждым вычислением значения и побочным эффектом второго (правого) аргумента.

Прочитайте здесь более подробное объяснение установленных правил: оценка заказа

Ответ 5

Он будет оценивать слева направо и кратковременно оценивать оценку, если это возможно (например, если оценка равна false, она не будет оценивать b).

Если вам небезразличен порядок, в котором они оцениваются, вам просто нужно указать их в желаемом порядке оценки в инструкции if.

Ответ 6

Оператор && всегда сначала обрабатывает свой левый операнд. Например:

if (a && b)
{
   //block of code
}

Если a является ложным, то b не будет оцениваться.

Если вы хотите сначала оценить b, а a, только если b - true, просто напишите выражение по-другому:

if (b && a)
{
   //block of code
}