在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吗?
谢谢
答案 0 :(得分:5)
正如所提到的here,mutable
说明符允许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;]代替通过引用进行捕获。