Пусть код говорит сам за себя первым с наивным подходом:
int heavy_calc() // needed to be called once
{
// sleep(7500000 years)
return 42;
}
int main()
{
auto foo = [] {
// And cached for lambda return value
static int cache = heavy_calc();
return cache;
};
return foo() + foo();
}
Я хочу, чтобы внутреннее кэшированное значение лямбды вычислялось при первом вызове.Наивным подходом является использование static
кеша, но он увеличивает двоичный размер и отказывается быть встроенным .
Я придумал создать cache
в списке захвата и пометить лямбду какmutable
, что встраивает без проблем , но требует, чтобы кэш начинался со значения по умолчанию, что может нарушить инвариант класса.
auto foo = [cache=0] () mutable {
// And cached for lambda return value
if(!cache)
cache = heavy_calc();
return cache;
};
Мой третий подход использует boost::optional
вmutable lambda
auto foo = [cache=std::optional<int>{}] () mutable {
// And cached for lambda return value
if(!cache)
cache = heavy_calc();
return *cache;
};
Работает нормально, но выглядит как своего рода список захвата + mutable
взлом ключевого слова.Также mutable
влияет на все записанные параметры, поэтому делает лямбду менее безопасной в реальном использовании.
Может быть, есть лучшее / более чистое решение для этого?Или просто другой подход, который приводит к тому же самому эффекту.
РЕДАКТИРОВАТЬ, некоторая предыстория: Лямбда-подход выбран, поскольку я изменяю некоторую лямбду обратного вызова, которая в настоящее время используется как: [this, param]{this->onEvent(heavy_calc(param));}
Я хочу уменьшить heavy_calc
звонки без предварительной оценки (только при первом звонке)