[英]Different results obtained by using generic lambdas and automatic return type feature in C++14
我试图用C ++在python中实现这段高阶函数:
def add1(x):
def helper():
nonlocal x
x += 1
return x
return helper
以下是我创建的三个版本:
#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;
}
产出是:
101
102
103
-------------------------------------------
4239465
4239466
4239467
-------------------------------------------
4201325
4201325
4201325
只有add1_v1符合我的要求。 谁能解释一下我的原因?
原因是这是未定义的行为。
内部lambda通过引用捕获x
。
问题是,只要add()
返回,其参数就会被销毁,并且返回的lambda会有一个对被破坏对象的悬空引用。
lambda必须按值捕获x
; 而你在我看来真正想做的是一个可变的lambda :
auto add(int x) {
function<int(void)> g = [x]() mutable {return ++x;};
return g;
}
请注意,这种方法在随后复制返回的lambda时会带来某些影响; 但只要返回的lambda保持“在一个地方”,在其剩余的生命周期中,所产生的语义可能就是你所期望的。
所有这些都是格式不正确的,因为你在lambda中通过引用捕获x
,但是x
是一个局部变量,当离开函数add
时会被破坏,然后引用变得悬挂,后面的引用会引起UB,这意味着一切皆有可能; 即便是第一种情况似乎工作正常。
如果将参数签名更改为add1_v *(int && x),似乎所有版本的函数都能正常运行
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.