Reputation: 247
I wanted to undersatnd variable i scope w.r.to lambda function. i is captured as by value So incrementation should only happen internally and it should not effect the global i value. So i expected output 1 1 1. But the output is 1 2 2
int i = 0;
auto a = [i]() mutable { cout << ++i << endl; };
a(); // i copies by value , So i value get changed internally in lambda function scope
auto b = a;
a(); // here why it is giving 2 instead of 1 ???
b();
What am i missing here ?
Upvotes: 1
Views: 2084
Reputation: 14614
Result of lambda expression is an object with operator()
. Code here
int i = 0;
auto a = [i]() mutable { cout << ++i << endl; };
a();
a();
results in behaviour roughly similar to this:
int i = 0;
struct local_lambda_01 {
private: // some older compilers skip this and in result there is an
// implementation detail that you can access following members
int i = ::i; // this is result of capture by value.
public:
void operator() { // it's not `const` because lambda is `mutable`
cout << ++i << endl; // it's `this->i`
}
} a; // a variable of local_lambda_01 type;
a(); // call to operator(), increments member i of local_lambda_01
a();
A copy of variable i
's value was stored at point of creation of callable a
instance. As lambda was declared mutable
, operator()
is not const-declared and can modify stored values. It doesn't change the original.
If we add statement
auto b = a;
after calling a()
, we perform copy on already modified instance of the object.
Upvotes: 2
Reputation: 172934
int i = 0;
auto a = [i]() mutable { cout << ++i << endl; }; // i is captured in a with value 0
a(); // i captured by a becomes 1
auto b = a; // b is copied from a, the captured i in b is copied with value 1 too
a(); // i captured by a becomes 2
b(); // i captured by b becomes 2
Upvotes: 1