C++ c++;带有意外结果的闭包

C++ c++;带有意外结果的闭包,c++,lambda,closures,C++,Lambda,Closures,我正在测试一些关于闭包的特性,但是我遇到了一些问题,这里有一些代码,有一个3个lambda函数的向量,这些函数捕获buildfn中的局部变量,所有I的内存位置都是相同的,但是,只有主函数的第一个调用实际输出了3,当我们在main中调用向量输出3中的所有函数时,我们是否应该期待它们 #include <iostream> #include <vector> using namespace std; auto BuildFns() { vector<function

我正在测试一些关于闭包的特性,但是我遇到了一些问题,这里有一些代码,有一个3个lambda函数的向量,这些函数捕获buildfn中的局部变量,所有I的内存位置都是相同的,但是,只有主函数的第一个调用实际输出了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]();
}
预期:

0xaddress_of_i
0xaddress_of_i
0xaddress_of_i
3
0xaddress_of_i
3
0xaddress_of_i
3
0xaddress_of_i

这里的问题是,您正在对超出范围(
i
)的局部变量执行引用捕获(
i
),即时
BuildFns()
返回。引用捕获也可以是指针,并且作为局部变量,在本例中可能是指向堆栈的指针。因此,您不应该对值随机更改感到惊讶。它所需要的只是
std::function
调用中的某种机制来写入堆栈,然后您的值就消失了


如果在创建闭包时确实需要
i
的值,请改为按值捕获。

变量
i
仅在循环内部是局部变量。循环完成后,变量将超出范围,其生命周期结束,任何指向它的指针或引用都将悬空且无效。使用该引用将导致@Someprogrammerdude好的,我认为闭包将延长我的生命周期
0xaddress_of_i
0xaddress_of_i
0xaddress_of_i
3
0xaddress_of_i
3
0xaddress_of_i
3
0xaddress_of_i