The need of the keyword mutable
in lambdas, is source of great confusion.
Consider the code:
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";
Output:
Before lambda: x = 10
Inside lambda: x = 11
After lambda: x = 10
As we can see, the variable x
stays unchanged after the lambda, so there are no side effects.
However, if we "forget" the keyword mutable, we get an error.
Being the argument passing by value the default in C++, it doesn't make sense for me the need of the mutable keyword.
Can someone write (even in pseudo code) the class generated by the compiler, in place of the lambda?
Thank you
As mentioned here the mutable
specifier allows the lambda to modify the parameters captured by copy and to call their non-const member functions. It doesn't affect variables captured by reference.
Can someone write (even in pseudo code) the class generated by the compiler, in place of the lambda?
It's not that easy to give a general case, but we can define something that is valid in your specific case.
The generated class would probably look like:
struct Lambda {
void operator()() { x++; }
int x{10};
};
If you remove the mutable
specifier, the function operator is defined as const
:
struct Lambda {
void operator()() const { x++; }
int x{10};
};
For simplicity I've initialized x
with the given value (10) and made it public, but it's obviously initialized by copy using the variable captured from the surrounding context and not accessible from outside the function operator.
Its type is deduced as well from the variable used to initialize it as if you do:
auto lambda_x = x;
See here for further details.
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;
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With