【问题标题】:Why can't I change the value of a variable captured by copy in a lambda function?为什么我不能更改 lambda 函数中复制捕获的变量的值?
【发布时间】:2017-03-30 21:46:24
【问题描述】:

我正在阅读 B. Stroustrup 在其第 11.4.3.4 节“可变 Lambdas”中的 C++ 编程语言,其中内容如下:

通常,我们不想修改函数对象的状态( 闭包),所以默认情况下我们不能。也就是说,operator()() 用于 生成的函数对象(§11.4.1)是一个const 成员函数。 在 我们想要修改状态的不太可能发生的事件(而不是 修改引用捕获的某些变量的状态; §11.4.3), 我们可以声明 lambda 是可变的

我不明白为什么当按值捕获变量时,operator()() 的默认值是 const。这有什么道理?当我更改复制到函数对象中的变量的值时会出现什么问题?

【问题讨论】:

  • 它在第一句话中说:“通常,我们不想修改函数对象的状态(闭包),所以默认情况下我们不能。”

标签: c++ lambda


【解决方案1】:

可以将 lambdas 视为具有operator()() 的类,默认情况下定义为const。也就是说,它不能改变对象的状态。因此,lambda 将作为常规函数运行,并在每次调用时产生相同的结果。相反,如果我们将 lambda 声明为可变的,则 lambda 可以修改对象的内部状态,并根据该状态为不同的调用提供不同的结果。这不是很直观,因此不鼓励。

例如,对于可变 lambda,可能会发生这种情况:

#include <iostream>

int main()
{
  int n = 0;
  auto lam = [=]() mutable {
    n += 1;
    return n;
  };

  std::cout << lam() << "\n";  // Prints 1
  std::cout << n << "\n";      // Prints 0
  std::cout << lam() << "\n";  // Prints 2
  std::cout << n << "\n";      // Prints 0
}

【讨论】:

  • 感谢您的回复。可以举一个例子说明 lambda 不会产生相同的结果,一旦我改变它的状态,使用一个按值传递给 lambda 表达式的变量?
  • 添加示例
  • 这个例子对我来说已经足够清楚了 (+1)。非常感谢。
【解决方案2】:

对 const 数据进行推理更容易。

通过默认 const,简短的 lamndas 更容易推理。如果你想要可变性,你可以要求它。

std 中的许多函数对象都被复制了;复制的 const 对象具有更简单的跟踪状态。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-29
    • 2021-10-22
    • 1970-01-01
    相关资源
    最近更新 更多