Che*_*hen 5 c++ python lambda c++14
我试图用C++在python中实现这段高阶函数:
def add1(x):
def helper():
nonlocal x
x += 1
return x
return helper
Run Code Online (Sandbox Code Playgroud)
以下是我创建的三个版本:
#include <iostream>
#include <functional>
using namespace std;
function<int(void)> add1_v1(int x) {
function<int(void)> g = [&x]() {return ++x;};
return g;
}
auto add1_v2(int x) {
function<int(void)> g = [&x]() {return ++x;};
return g;
}
auto add1_v3(int x) {
auto g = [&x]() {return ++x;};
return g;
}
int main() {
auto a = add1_v1(100);
auto b = add1_v2(100);
auto c = add1_v3(100);
for(int i = 0; i < 3; ++i) {
cout << a() << endl;
}
cout << "-------------------------------------------" << endl;
for(int i = 0; i < 3; ++i) {
cout << b() << endl;
}
cout << "-------------------------------------------" << endl;
for(int i = 0; i < 3; ++i) {
cout << c() << endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
产出是:
101
102
103
-------------------------------------------
4239465
4239466
4239467
-------------------------------------------
4201325
4201325
4201325
Run Code Online (Sandbox Code Playgroud)
只有add1_v1符合我的要求.谁能解释一下我的原因?
原因是这是未定义的行为.
内部lambda x通过引用捕获.
问题是,只要add()返回,它的参数就会被销毁,并且返回的lambda会有一个对被破坏对象的悬空引用.
lambda必须x按值捕获; 而你在我看来真正想做的是一个可变的lambda:
auto add(int x) {
function<int(void)> g = [x]() mutable {return ++x;};
return g;
}
Run Code Online (Sandbox Code Playgroud)
请注意,这种方法在随后复制返回的lambda时会带来某些影响; 但只要返回的lambda保持"在一个地方",在其剩余的生命周期中,所产生的语义可能就是你所期望的.