gpt4 book ai didi

c++ - 什么时候捕获捕获变量?

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:14:52 24 4
gpt4 key购买 nike

我正在制作回调 std::functionstd::vector,但我在理解捕获时遇到了一些麻烦。如果我通过引用捕获,当我尝试使用它们时,它们似乎超出了范围。如果我按值(value)捕获,一切正常。

使用这些回调函数的代码需要一个特定的签名,所以假设我不能修改使用这些函数的代码,我需要坚持使用捕获变量而不是将东西作为函数参数传递。

什么时候 localVar 被捕获?是在定义 lambda 时还是在调用时?答案是否会根据我是按值捕获还是按引用捕获而改变?

这里有一个我想理解的小例子:

#include <iostream>
#include <functional>
#include <vector>

int main(int argc, char **argv)
{

int n(5);

// make a vector of lambda functions
std::vector<std::function<const int(void)> > fs;
for(size_t i = 0; i < n; ++i){
int localVar = i;
auto my_lambda = [&localVar]()->int // change &localVar to localVar and it works
{
return localVar+100;
};
fs.push_back(my_lambda);
}

// use the vector of lambda functions
for(size_t i = 0; i < n; ++i){
std::cout << fs[i]() << "\n";
}


return 0;
}

最佳答案

引用 在您创建 lambda 时被捕获。永远不会捕获所引用对象的。当您调用 lambda 时,无论您何时使用它(就像使用任何其他引用一样),它都会使用引用来确定引用对象的值。如果在引用的对象不复存在后使用引用,则您使用的是悬空引用,这是未定义的行为。

在这种情况下,auto my_lambda = [&localVar]()->int使用名为 localVar 的引用创建一个 lambda到局部变量 localVar .

std::cout << fs[i]() << "\n";调用其中一个 lambda。但是,当 lambda 执行 return localVar+100; ,它正在尝试使用引用 localVar到局部变量 localVar (第一个 for 循环的局部变量)但该局部变量不再存在。你有未定义的行为。

如果您放下与号并取 localVar按值 ( auto my_lambda = [localVar]()->int ),您将捕获创建 lambda 时值的拷贝。因为它是一个拷贝,原始 localVar 发生什么并不重要.

您可以在 http://en.cppreference.com/w/cpp/language/lambda#Lambda_capture 阅读相关内容

关于c++ - 什么时候捕获捕获变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49181828/

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