1

我有一个非常简单的递归 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得到参数firstas2并且 argsecond也是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

How issum_v2在创建 lambda 时,将 argfirst视为 2。我很难理解这一点。

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

谢谢,高拉夫

4

1 回答 1

3

这:

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

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

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

于 2020-02-02T01:57:47.103 回答