In C++ you can declare lambdas for example like this:
int x = 5; auto a = [=]() mutable { ++x; std::cout << x << '\n'; }; auto b = [&]() { ++x; std::cout << x << '\n'; }; Both let me modify x, so what is the difference?
The first will only modify its own copy of x and leave the outside x unchanged. The second will modify the outside x.
Add a print statement after trying each:
a(); std::cout << x << "----\n"; b(); std::cout << x << '\n'; This is expected to print:
6 5 ---- 6 6 It may help to consider that lambda
[...] expressions provide a concise way to create simple function objects
(see [expr.prim.lambda] of the Standard)
They have
[...] a public inline function call operator [...]
which is declared as a const member function, but only
[...] if and only if the lambda expression’s parameter-declaration-clause is not followed by
mutable
You can think of as if
int x = 5; auto a = [=]() mutable { ++x; std::cout << x << '\n'; }; ==> int x = 5; class __lambda_a { int x; public: __lambda_a () : x($lookup-one-outer$::x) {} inline void operator() { ++x; std::cout << x << '\n'; } } a; and
auto b = [&]() { ++x; std::cout << x << '\n'; }; ==> int x = 5; class __lambda_b { int &x; public: __lambda_b() : x($lookup-one-outer$::x) {} inline void operator() const { ++x; std::cout << x << '\n'; } // ^^^^^ } b; Q: But if it is a const function, why can I still change x?
A: You are only changing the outside x. The lambda's own x is a reference, and the operation ++x does not modify the reference, but the refered value.
This works because in C++, the constness of a pointer/reference does not change the constness of the pointee/referencee seen through it.
a some places you meant b. And your objects of anonymous class type don't have initializers. Might want to explain we're pretending lambda_a() is a constructor although the class has no name.const actually makes no difference. You always mutate the referencee through a reference. But to give another example: int main () { int x; auto a = [=]() { ++x; }; }. g++ will give an error message for that because the [=] means that the generated function object gets its own member variable x, but the lack of mutable means that a const member function call operator is generated, therefore the x is not assignable.auto c = [=]() { ++x; }; above would give more clarity on why mutable, and there by const, makes a difference.mutable qualification should be by default, and const specification should be explicit.int sum = 0; std::for_each(vec.cbegin(), vec.cend(), [sum](int x) { sum += x;}).