Lambda按值捕获和"可变"关键词

时间:2017-02-05 19:44:38

标签: c++ lambda

在lambdas中需要关键字mutable,这是一个非常困惑的来源。

考虑代码:

int x = 10;

function<void()> lambda = [=]() mutable {x++; cout << "Inside lambda: x = " << x << "\n";};

cout << "Before lambda: x = " << x << "\n";
lambda();
cout << "After  lambda: x = " << x << "\n\n";

输出:

Before lambda: x = 10
Inside lambda: x = 11
After  lambda: x = 10

正如我们所看到的,变量x在lambda之后保持不变,因此没有副作用。

然而,如果我们忘记&#34;关键字 mutable ,我们收到错误消息。

作为通过值传递的参数是C ++中的默认值,对我来说, mutable 关键字的需要并没有意义。

有人可以编写(甚至是伪代码)编译器生成的类来代替lambda吗?

谢谢

3 个答案:

答案 0 :(得分:5)

正如所提到的heremutable说明符允许lambda修改由副本捕获的参数并调用它们的非const成员函数。它不会影响通过引用捕获的变量。

  

有人可以编写(甚至是伪代码)编译器生成的类来代替lambda吗?

提供一般情况并不容易,但我们可以定义在您的具体情况下有效的内容 生成的类可能看起来像:

struct Lambda {
    void operator()() { x++; }
    int x{10};
};

如果删除mutable说明符,则函数运算符定义为const

struct Lambda {
    void operator()() const { x++; }
    int x{10};
};

为简单起见,我已使用给定值(10)初始化x并将其公之于众,但它显然是使用从周围上下文捕获的变量进行复制初始化的,并且无法从函数运算符外部访问。登记/> 它的类型也可以从用于初始化它的变量中推导出来,就好像你这样做:

auto lambda_x = x;

有关详细信息,请参阅here

答案 1 :(得分:1)

class Lambda
{
public:
   Lambda(const Lambda&);
   ~Lambda();

   // the main functor operator, const when lambda not mutable
   R operator()(Args args) const;

   // Only present for non-capture lambda         
   operator PlainCFunctionType () const; 

   // Only present for non-capture  lambda         
   PlainCFunctionType operator+() const;
private:
   // Gets called when lambda created, but you can't call it yourself
   Lambda(Captures captures...); 

   Captures captures;
};

答案 2 :(得分:1)

你并不是真的以面向对象的方式编写代码,但无论如何。 通常,[=]添加的外部变量是const值。通过添加mutable关键字,您可以创建它们的本地可修改副本。 您可以使用[&amp;]代替通过引用进行捕获。