我正在测试一些关于闭包的功能,但我遇到了一些问题,这里有一些代码,有3个lambda函数的向量,这些函数捕获BuildFns中的局部变量,我所有的内存位置是相同的,但是,只有主函数的第一次调用实际输出3,当我们在main中调用它们时,我们是否应该期望向量输出3中的所有函数?
#include <iostream>
#include <vector>
using namespace std;
auto BuildFns() {
vector<function<void()>> vec;
for (int i = 0; i < 3; i++) {
cout << &i << '\n';
vec.push_back([&i]() {
cout << i << endl;
cout << &i << '\n';
});
}
return vec;
}
auto main() -> int {
auto vec = BuildFns();
vec[0]();
vec[1]();
vec[2]();
}
输出:
0x7ffeedfa25c8
0x7ffeedfa25c8
0x7ffeedfa25c8
3
0x7ffeedfa25c8
-1581316512 // what's wrong with this i? isn't it contained in the closure environment and can't be written if it's still been accessed?
0x7ffeedfa25c8
-1581316512
0x7ffeedfa25c8
预期:
0xaddress_of_i
0xaddress_of_i
0xaddress_of_i
3
0xaddress_of_i
3
0xaddress_of_i
3
0xaddress_of_i
答案 0 :(得分:1)
这里的问题是你正在通过引用(&i
)对超出范围(i
)的本地变量进行捕获BuildFns()
。通过引用捕获也可以是指针,并且作为局部变量,在这种情况下可能是指向堆栈的指针。因此,您不应对该值随机变化感到惊讶。所需要的只是std::function
调用中的某些机制写入堆栈,然后你的价值就消失了。
如果您在创建闭包时确实需要i
的值,请改为按值捕获。