繁体   English   中英

在C ++ 14中使用通用lambdas和自动返回类型功能获得的结果不同

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM