【发布时间】:2018-03-08 20:23:58
【问题描述】:
我正在制作一个回调std::functions 的std::vector,但我在理解捕获时遇到了一些麻烦。如果我通过引用捕获,当我尝试使用它们时,它们似乎超出了范围。如果我按价值捕获,那么一切正常。
使用这些回调函数的代码需要特定的签名,因此假设我无法修改使用这些回调函数的代码,我需要坚持使用捕获变量而不是将事物作为函数参数传递。
什么时候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;
}
【问题讨论】:
-
在
auto my_lambda = [&localVar]()->int行中捕获了对localVar的引用。然后你执行push_back,然后localVar消失,如果你调用 lambda,你有未定义的行为。 -
想象
fs是std::vector<int*>,而在循环中你做了fs.push_back(&localVar)。退出定义localVar的块后,您是否希望存储的指针有效? -
您可以将 lambda 视为具有重载
operator()的类的实例。如果你通过引用捕获它就像拥有一个类的引用成员;您必须注意,当仍在调用 lambda 的实例时,所引用的对象不会停止存在
标签: c++ c++11 lambda std-function