为什么 C 11 的 lambda 默认需要“可变”关键字用于按值捕获?

新手上路,请多包涵

简短的例子:

 #include <iostream>

int main()
{
    int n;
    [&](){n = 10;}();             // OK
    [=]() mutable {n = 20;}();    // OK
    // [=](){n = 10;}();          // Error: a by-value capture cannot be modified in a non-mutable lambda
    std::cout << n << "\n";       // "10"
}

问题:为什么我们需要 mutable 关键字?它与传统的参数传递给命名函数完全不同。背后的原理是什么?

我的印象是,按值捕获的全部意义在于允许用户更改临时值——否则我几乎总是最好使用按引用捕获,不是吗?

有什么启示吗?

(顺便说一下,我正在使用 MSVC2010。AFAIK 这应该是标准的)

原文由 kizzx2 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 505
2 个回答

它需要 mutable 因为默认情况下,函数对象每次调用时都应该产生相同的结果。这是面向对象函数和使用全局变量的函数之间的区别,有效。

原文由 Puppy 发布,翻译遵循 CC BY-SA 2.5 许可协议

您必须了解捕获的含义!它捕获的不是参数传递!让我们看一些代码示例:

 int main()
{
    using namespace std;
    int x = 5;
    int y;
    auto lamb = [x]() {return x + 5; };

    y= lamb();
    cout << y<<","<< x << endl; //outputs 10,5
    x = 20;
    y = lamb();
    cout << y << "," << x << endl; //output 10,20

}

As you can see even though x has been changed to 20 the lambda is still returning 10 ( x is still 5 inside the lambda ) 在 lambda 内部更改 x 意味着在每次调用时更改 lambda 本身(每次调用时 lambda 都会发生变异)。为了确保正确性,标准引入了 mutable 关键字。通过将 lambda 指定为可变的,您是说每次调用 lambda 都可能导致 lambda 本身发生变化。再看一个例子:

 int main()
{
    using namespace std;
    int x = 5;
    int y;
    auto lamb = [x]() mutable {return x++ + 5; };

    y= lamb();
    cout << y<<","<< x << endl; //outputs 10,5
    x = 20;
    y = lamb();
    cout << y << "," << x << endl; //outputs 11,20

}

上面的例子表明,通过使 lambda 可变,更改 x 在 lambda 内部“变异” lambda 在每次调用时使用新值 x 这与 x 在主函数中的实际值

原文由 Soulimane Mammar 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题