Lambda按值捕获和"mutable"关键字

Arn*_*sen 5 c++ lambda

mutablelambdas中关键字的需求是一个非常混乱的根源.

考虑一下代码:

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";
Run Code Online (Sandbox Code Playgroud)

输出:

Before lambda: x = 10
Inside lambda: x = 11
After  lambda: x = 10
Run Code Online (Sandbox Code Playgroud)

我们可以看到,变量x在lambda之后保持不变,因此没有副作用.

但是,如果我们"忘记"关键字mutable,我们会收到错误.

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

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

谢谢

sky*_*ack 5

如前所述这里mutable允许拉姆达修改通过复制所拍摄的参数,并呼吁其非const成员函数.它不会影响通过引用捕获的变量.

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

给出一般情况并不容易,但我们可以定义在特定情况下有效的东西.
生成的类可能如下所示:

struct Lambda {
    void operator()() { x++; }
    int x{10};
};
Run Code Online (Sandbox Code Playgroud)

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

struct Lambda {
    void operator()() const { x++; }
    int x{10};
};
Run Code Online (Sandbox Code Playgroud)

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

auto lambda_x = x;
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参见此处


Ale*_*iev 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;
};
Run Code Online (Sandbox Code Playgroud)