首先用简单的方法让代码自己说话:
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();
}
我想在第一次调用时计算 lambda 内部缓存值。一个天真的方法是使用static
缓存,但是它增加二进制大小并拒绝内联 https://godbolt.org/z/0kQN_e.
我想出了创造cache
在捕获列表中并将 lambda 标记为mutable
, what 内联没有问题 https://godbolt.org/z/K37Psw,但要求缓存以默认值启动,这可能会破坏类不变性。
auto foo = [cache=0] () mutable {
// And cached for lambda return value
if(!cache)
cache = heavy_calc();
return cache;
};
我的第三种方法使用boost::optional在可变的lambda https://godbolt.org/z/mTpZvT
auto foo = [cache=std::optional<int>{}] () mutable {
// And cached for lambda return value
if(!cache)
cache = heavy_calc();
return *cache;
};
它工作正常,但对我来说就像捕获列表+mutable
关键字黑客。还mutable
影响所有捕获的参数,因此使得 lambda 在实际使用中不太安全。
也许有更好/更干净的解决方案?或者只是不同的方法,最终会产生完全相同的效果。
编辑,一些背景:
选择 Lambda 方法是因为我正在修改一些回调 lambda,目前用作:[this, param]{this->onEvent(heavy_calc(param));}
我想减少heavy_calc
调用时不提前评估(仅在第一次调用时)