[英]Why can't I capture a recursive lambda function in C++?
I find that if a lambda is a recursive function which is calling itself, then it can't be captured by another lambda as working in a closure in C++. 我发现,如果lambda是调用自身的递归函数,则不能像在C ++中的闭包中那样被另一个lambda捕获。
I have some codes like this: 我有一些这样的代码:
#include <memory>
#include <functional>
#include <iostream>
class ClassA
{
public:
std::function<void()> FuncA;
void Call()
{
FuncA();
}
};
class ClassB
{
std::unique_ptr<ClassA> pA = std::make_unique<ClassA>();
public:
void Setup()
{
std::function<void(int)> FuncB = [&](int a)
{
std::cout << "a = " << a << std::endl;
if(a > 0)
FuncB(a-1);
};
pA->FuncA = [&]()
{
FuncB(10.0f);
};
}
void Run()
{
Setup();
pA->Call();
}
};
int main() {
ClassB B;
B.Run();
}
a exception will occur when running to calling FuncA, because FuncB in it will be a empty pointer. 调用FuncA时会发生异常,因为其中的FuncB将为空指针。
My question is why can't I capture a recursive lambda function? 我的问题是为什么我不能捕获递归lambda函数?
I'm using Visual Studio 2015 我正在使用Visual Studio 2015
EDIT: If capture FuncB by copy in FuncA, then it works if FuncB is not recursive. 编辑:如果通过复制在FuncA中捕获FuncB,则如果FuncB不是递归的,则可以使用。 like this:
像这样:
class ClassB
{
std::unique_ptr<ClassA> pA = std::make_unique<ClassA>();
public:
void Setup()
{
std::function<void(int)> FuncB = [FuncB](int a)
{
std::cout << "a = " << a << std::endl;
if (a > 0)
FuncB(a - 1);
};
pA->FuncA = [FuncB]()
{
FuncB(10.0f);
};
}
void Run()
{
Setup();
pA->Call();
}
};
You're capturing FuncB
by reference, but FuncB
is destroyed when Setup
returns, leaving you with a dangling reference. 您正在通过引用捕获
FuncB
,但是在Setup
返回时FuncB
被破坏,留下了悬挂的引用。
If you change FuncB
to be captured by value, then the first lambda captures it before it is initialized, which leads to undefined behavior. 如果将
FuncB
更改为按值捕获,则第一个lambda会在对其进行初始化之前捕获它,这将导致未定义的行为。
I can't think of any way to get a lambda to capture itself, like you are trying to do. 我想不出任何办法来获取lambda来捕获自己,就像您尝试做的那样。
Made small modifications to your code, and this works fine: 对您的代码进行少量修改,可以正常工作:
#include <iostream>
#include <functional>
struct A
{
std::function<void()> fa;
void call() { fa(); }
};
struct B
{
A *pA;
B() {pA=nullptr; }
typedef std::function<void(int)> FB;
FB fb;
void Setup()
{
fb=[&](int i)
{
std::cout << "i = " << i << "\n";
if(i > 0) fb(i-1);
};
if (pA) { pA->fa=[&]() { fb(10.0f); }; }
}
void Run(A*p)
{
pA=p;
Setup();
pA->call();
}
};
int main()
{
A a;
B b;
b.Run(&a);
return 0;
}
Maybe this will help you refine your algorithm. 也许这将帮助您完善算法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.