Как извлечь выгоду из ленивого вычисления логических операторов, сохранив лаконичность кода? [дубликат]C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Как извлечь выгоду из ленивого вычисления логических операторов, сохранив лаконичность кода? [дубликат]

Сообщение Anonymous »

На примере кода:

Код: Выделить всё

const bool b1 = fn1();  // Long-running function without side effects
const bool b2 = fn2(); // Long-running function without side effects
const bool cond = b1 || b2;
// Code that uses cond
Очевидно, что оператор || использует отложенное вычисление. Если b1 истинно, он не будет оценивать b2.
Вопрос в том, что насчет const bool b2 = fn2()? Здесь я вижу три возможных ответа:
  • b2 будет вычисляться и вызываться fn2 независимо от значения b1, так как это разные последовательные операторы (скорее всего для меня).
  • это полностью зависит от оптимизатора и не предусмотрено стандартом; оптимизатор может пропустить вычисление b2 и вызов fn2, если он может гарантировать отсутствие побочных эффектов и т. д. (может быть и так).
  • b2 не будет рассчитываться и fn2 не будет вызывается, если b1 истинно, поскольку этот код проверки ленивой оценки встроен в представление кода абстрактного синтаксического дерева при его компиляции и будет автоматически опущен любым разумным компилятором. (Я вообще не верю, что такое может быть. В любом случае, оставим это здесь).
(Буду благодарен за точную информацию стандарту языковых юристов здесь).
Если 3 не является правильным (что, я уверен, неверно), мне нужен надежный способ извлечь выгоду из ленивых вычислений.
Конечно, в этом простом сценарии это будет:

Код: Выделить всё

const bool cond = fn1() || fn2();
// Code that uses cond
Но что, если эти вызовы гораздо более многословны и если поместить их в одну строку, они станут нечитаемыми:

Код: Выделить всё

const bool keep_all_values =
update_strategy_branches ||
0 == std::count_if(database.begin(), database.end(),
[=](const MyTypeToGetAccessToMembersInIDE& value) { return value.member->field == some_value; });
Как лучше всего извлечь второй оператор из || здесь? Должен ли я обернуть его в лямбду, которая возвращает лямбду и фиксирует все используемые переменные (

Код: Выделить всё

database 
, some_value)? Каков рекомендуемый способ сохранить краткий код и получить выгоду от ленивых вычислений?
Обновление по запросу из комментариев ниже и закрытие
Пожалуйста, не путайте этот вопрос с вопросом: обязательно ли сокращение логических операторов? И порядок оценки? и много подобных вопросов, которые намного проще и могут возникнуть перед этим. Я знаю, как работает ленивое вычисление для этих операторов, и знаю, когда и зачем его использовать. Мой вопрос следующий после этих вопросов: влияет ли это на расчет предыдущих утверждений и как еще можно извлечь выгоду из ленивых вычислений, если нет?
Пожалуйста, не путайте с вопросами:
Пожалуйста, не путайте с вопросами:
  • Могут ли оптимизаторы C/C++ решить лениво оценивать значения, которые используются только в сокращенной оценке?; на этот вопрос так и не ответили, поэтому он никоим образом не затрагивает текущий. Но главное в том, что он отвечает на первые подвопросы (предположения) моего вопроса, а именно, как ведут себя компиляторы; у меня вопрос другой, а именно как с этим справиться.
  • Разрешается ли оптимизирующему компилятору опускать вызов функции, косвенно используемый в коротком замыкании?; тот же вопрос, что и выше, хотя на него есть ответ, он отвечает только на приведенный выше подвопрос-предположение. Мой вопрос в другом; см. выше.


Подробнее здесь: https://stackoverflow.com/questions/793 ... de-concise
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

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

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»