c ++ lambda:求和函数:使用按值捕获和按引用捕获返回不同的结果

时间:2020-02-02 01:35:55

标签: c++ lambda functional-programming currying generic-lambda

我有一个非常简单的递归lambda,它可以计算给定2个数字的和:

auto sum_v1 = [](auto first){
  return [first](auto second){
    return first + second;
  };
};

sum_v1 (1)(2); // returns 3, OK

现在具有相同的功能,首先对arg使用引用捕获。

auto sum_v2 = [](auto first){
  return [&first](auto second){
    return first + second;
  };
};

sum_v2 (1)(2); // returns 4, NOT OK

sum_v2的参数first2,arg second也是2

我知道如何获得正确的结果。我可以使用sum_v1或sum_v3(如下所示)。

// accept arg first using r-value reference
auto sum_v3 = [](auto&& first){
  return [first](auto second){
    return first + second;
  };
};

sum_v3 (1)(2); // returns 3, OK

sum_v2在创建lambda的同时,如何将参数first视为2。我正在努力理解这一点。

能否请您给我一些提示以更好地理解这一点?我在rhel 7上使用带有-std = c ++ 17的gcc.9.2.0。

谢谢, 高拉夫

1 个答案:

答案 0 :(得分:3)

此:

auto sum_v2 = [](auto first){
  return [&first](auto second){
    return first + second;
  };
};

是未定义的行为,因为您要引用局部变量first,该变量的生命周期在使用前就结束了。与所有UB一样,任何事情都可能发生。在您的计算机上,似乎first最终引用了second,但这并不能保证。该代码可能会在其他系统上崩溃,或产生预期的结果,但是您不能依靠它。

使用-Wall -Werror甚至无法编译此错误代码。演示:https://godbolt.org/z/3gYx7q