如果函数返回的lambda捕获并变异了在函数范围内声明的值,那么该值在哪里/如何存储在内存中,以便lambda可以安全地使用它?
此示例摘自IvanČukić在“ C ++中的函数编程”中的清单6.7。这是一种实用工具备忘方法,可缓存结果以便以后快速查找。人为设计的使用方法将进行计算,然后检索缓存的斐波那契数:
#include <iostream>
#include <map>
#include <tuple>
template <typename Result, typename... Args>
auto make_memoized(Result (*f)(Args...)) {
std::map<std::tuple<Args...>, Result> cache;
return [f, cache](Args... args) mutable -> Result {
const auto args_tuple = std::make_tuple(args...);
const auto cached = cache.find(args_tuple);
if (cached == cache.end()) {
auto result = f(args...);
cache[args_tuple] = result;
return result;
} else {
return cached->second;
}
};
}
unsigned int fib(unsigned int n) {
return n < 2 ? n : fib(n - 1) + fib(n - 2);
}
int main() {
auto fibmemo = make_memoized(fib);
std::cout << "fib(15) = " << fibmemo(15) << '\n';
std::cout << "fib(15) = " << fibmemo(15) << '\n';
}
我的期望是cache
返回时make_memoized
将被销毁,因此对lambda的追溯调用将引用超出范围的值。但是,它可以正常工作(在OSX上为g ++ 9.1)。
我在cppreference.com上找不到这种用法的具体示例。非常感谢您为我提供正确的搜索术语帮助。
答案 0 :(得分:2)
[f, cache]
通过值捕获变量。按值捕获后,捕获的var的寿命应与lambda本身相同。
编辑:如果通过引用(例如[f, &cache]
)捕获,则cache
和lambda的生存期将不再链接。因此,尽管代码仍然可以编译,但是使用返回的lambda不再安全,因为cache
已经被破坏了。