gpt4 book ai didi

意外结果的 C++ 闭包

转载 作者:行者123 更新时间:2023-11-28 04:38:48 25 4
gpt4 key购买 nike

我正在测试一些关于闭包的特性,但我遇到了一些问题,这里有一些代码,有一个包含 3 个 lambda 函数的 vector ,这些函数捕获 BuildFns 中的局部变量,所有 i 的内存位置都是相同的,但是,只有 main 函数的第一次调用实际输出 3,当我们在 main 中调用它们时,我们是否应该期望 vector 输出 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

最佳答案

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

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

关于意外结果的 C++ 闭包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50711704/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com