🤖
LifeEXE
Udemy курс UE / C++ PatreonBoostyTelegramYouTube
  • 🤍Welcome
  • 💡Мои курсы
    • 🎮Unreal Engine — полное руководство по разработке на С++
    • 🧪Автоматизация и тестирование в Unreal Engine
    • 🐍Snake game
    • 🔊Metasounds
    • 🏗️Design patterns
    • 🕹️Game Engine hardCORE series
    • 🧠OpenAI
  • 🔗Сообщество
    • Ресуры
    • Поддержать проект
    • Проекты участников сообщества
    • Code review участников сообщества
  • 📚Образовательные ресурсы
    • Книги
      • C++
      • ООП
      • Чистый код
      • Компьютерная графика
      • Алгоритмы и структуры данных
      • Дизайн и проектирование
      • Виртуальная реальность
      • Процедурная графика
      • Функциональное программирование
      • Менеджмент проектов
      • Фундаментальное
      • Тестирование
      • Разное
    • Online
      • Unreal Engine
      • C++
      • Компьютерная графика
      • Чистый код
      • AI
      • Разное
    • Статьи
      • Code / C++
  • 👨‍💻Software
    • IDE
      • VS hotkeys
    • Unreal Engine
    • GIT
    • CI/CD
    • Tools
      • С++
      • Компьютерная графика
      • UI / UX
      • Animations
      • GameDev
      • Unreal Engine
      • Creative coding
      • Sound
      • Документация
      • Статический анализ кода
      • Тестирование
      • Автоматизация
      • Network
      • CV / ML
      • Profiling
      • Fonts
      • UML / diagrams
      • Разное
    • Free assets
  • 💾Code
    • Code style
      • .clang-format
      • .gitignore
      • UE code style
      • Code style проектов LifeEXE
    • C++
      • Const correctness
      • Использование auto
      • Lambda выражения
      • Forward declaration
      • Measure execution time
      • Immediately Invoked Lambda Expression (IILE)
    • Unreal Engine
      • Медленный ли Cast
      • UE_LOGFMT
  • ⁉️FAQ
    • Часто задаваемые вопросы
Powered by GitBook
On this page
  • Почему const — это важно?
  • Проблематика
  • Immediately Invoked Lambda Expression (IILE)
  • Преимущества IILE для инициализации:
  • Альтернативный синтаксис (C++17):
  • Ссылки

Was this helpful?

  1. Code
  2. C++

Immediately Invoked Lambda Expression (IILE)

PreviousMeasure execution timeNextUnreal Engine

Last updated 27 days ago

Was this helpful?

Почему const — это важно?

Неизменяемость (immutability) — залог надежного и понятного кода. Использование const там, где это возможно, помогает компилятору отлавливать ошибки и делает намерения программиста яснее. Когда другой человек читает ваш код и видит const, снижается когнитивная нагрузка на мозг — «запоминать изменения данного значения не надо, расслабься». Принцип является одной из важнейших практик в C++.

Проблематика

В простых случаях инициализация констант не вызывает проблем:

const int c_maxPlayers = 100;
const double c_scaleFactor = getScaleFactor() * 1.5;
const bool c_enabled = checkFlag() || FORCE_ENABLE;
const int c_healthModifier = bHealing ? 20 : 0;

Но что делать, если для вычисления значения константы требуется несколько шагов, временные переменные, циклы или условия?

float c_calculatedDamage = getBaseDamageValue();
if (targetAimed(calculatedDamage)) {
    for (int i = 0; i < c_effectCount; ++i) {
        calculatedDamage += getBonusDamage(i);
    }
}

Традиционные подходы — вынести логику в отдельную именованную функцию или отказаться от const — не всегда идеальны. Создание отдельной функции может быть избыточным, если логика используется только один раз. Отказ от const снижает безопасность и выразительность кода.

Immediately Invoked Lambda Expression (IILE)

Здесь на помощь приходит использование немедленно вызываемого лямбда-выражения (IILE). Мы определяем лямбда-функцию, которая инкапсулирует всю сложную логику инициализации, и тут же вызываем её. Результат этого вызова и присваивается нашей константе.

Как это выглядит:

const auto myBeautifulLambda = [](){ return 13; }();

То есть мы можем проинициализировать сложный объект и сохранить константность:

const auto c_calculatedDamage = [&]() {
  float tempDamage = getBaseDamageValue();
  if (targetAimed(tempDamage)) {
      for (int i = 0; i < c_effectCount; ++i) {
          tempDamage += getBonusDamage(i);
      }
  }
  return tempDamage;
}();

Преимущества IILE для инициализации:

  • Инкапсуляция: вся логика инициализации собрана в одном месте.

  • Локальность: временные переменные, используемые для вычисления, не "загрязняют" внешнюю область видимости.

  • const сorrectness: позволяет объявить переменную как const (или даже constexpr, если лямбда соответствует требованиям), даже если её вычисление многоэтапное.

  • Чистота кода: избавляет от необходимости создавать отдельные, одноразовые именованные функции.

Альтернативный синтаксис (C++17):

В C++17 можно использовать std::invoke, хотя для IILE прямой вызов () обычно предпочтительнее и понятнее:

#include <functional> 
// ...
const auto c_anotherConstant = std::invoke([] {
    // ... 
    return 13;
});

Ссылки

Скобочки форева Последние круглые скобки () после фигурных скобок лямбды — это и есть немедленный вызов. Они заставляют лямбду выполниться прямо в месте определения.

💾
😄
const correctness
ES.28: Use lambdas for complex initialization, especially of const variables