Непостоянная рубрика: Субботний C++
Сегодня в меню очевидный, но не всегда применяемый подход:
Immediately Invoked Lambda Expression (IILE)
Почему const — это важно?
Неизменяемость (immutability) — залог надежного и понятного кода. Использование const там, где это возможно, помогает компилятору отлавливать ошибки и показывает намерения программиста яснее. Когда другой человек читает ваш код и видит const, снижается когнитивная нагрузка на мозг — «запоминать изменения данного значения не надо — расслабься». Const correctness является важной практикой в C++.
Проблематика
В простых случаях инициализация констант не вызывает проблем:
const int c_maxPlayers = 100;
const double c_scale = getScaleFactor() * 1.5;
const bool c_enabled = check() || 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 myLambda = [](){ 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 (или даже constexpr, если лямбда соответствует требованиям), даже если её вычисление многоэтапное.Альтернативный синтаксис (C++17)
В C++17 можно использовать
std::invoke, хотя для IILE прямой вызов () обычно предпочтительнее и понятнее:#include <functional>
// ...
const auto c_anotherConstant = std::invoke([] {
// ...
return 13;
});
Ссылки
Patreon | Boosty | PayPal
GitHub | LifeEXE School | Itch | X | Wiki | Курс по UE
#cpp #tips_and_tricks #code #fun #lifeexe #lifeexecode #lifeexeEDU
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥84❤17👍10❤🔥2