我一直在努力解决lambda表达式的一个问题,这个问题正在破坏我的一个项目。我找到了一个解决方案,但我想确切地了解它的工作原理和原因,以及它是否可靠。
#include <iostream>
#include <functional>
#include <unordered_map>
typedef std::function<const int&(const int&)> Callback;
int f(int i, Callback callback) {
if (i <= 2) return 1;
return callback(i-1) + callback(i-2);
}
int main(void) {
std::unordered_map<int, int> values;
Callback callback = [&](const int& i) {
if (values.find(i) == values.end()) {
int v = f(i, callback);
values.emplace(i, v);
}
return values.at(i);
};
std::cout << f(20, callback) << std::endl;
return 0;
}
我知道这是计算第20个Fibonacci数的一种疯狂方法,但它是我能够详细说明的最紧凑的SSCCE。
如果我用上面的代码编译 g++ -O0
我得到了执行程序 6765
,这实际上是第20个斐波纳契数。如果我编译 -O1
, -O2
要么 -O3
我明白了 262144
,这是垃圾。
如果我用Valgrind配置程序(用。编译) -O0 -g
),我明白了 Conditional jump or move depends on uninitialised value(s)
在线上 std::cout << f(20, callback) << std::endl;
但堆栈跟踪没有说任何有用的东西。
我不知道为什么我最终得到了这个:
Callback callback = [&](const int& i) -> const int& {
通过这一点修改,一切都按预期编译任何优化级别,Valgrind报告没有问题。
你能帮我理解发生了什么吗?