时间:2019-05-10 标签:c++lambda: Currying sum function: returns different results using capture by value vs by reference

标签 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 时,看到 arg first作为 2. 我很难理解这一点。

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

谢谢,
高拉夫

最佳答案

这:

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

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

-Wall -Werror你甚至无法编译这个糟糕的代码。演示:https://godbolt.org/z/3gYx7q

关于时间:2019-05-10 标签:c++lambda: Currying sum function: returns different results using capture by value vs by reference,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60022579/

相关文章:

c++ - std::mt19937 是否需要预热?

c++ - 关于 lambda 重载、类型转换和完美转发的问题

c++ - 从 lambda 返回对象/右值引用的首选形式

function - 这些功能函数叫什么?

c++ - 将 python 与 C++ 集成

java - 为什么 C 和 C++ IDE 工具支持落后于可用于托管平台的工具?

c++ - 在C++中的本地范围内使用Lambda

javascript - 从单参数函数应用程序到在节点中使用 async/await 进行数组映射

arrays - 你如何在普通的 lisp 中复制一个数组?

c++ - 关于指针的一些问题