Reputation: 64
I am trying to increment a captured variable to a lambda function by reference but unable to do so.
By capturing the variable by value and then making the lambda mutable, I am able to increment the value. But by passing the reference, the increment is not getting applied.
Also, In case of capture by value, how the value is getting updated across the calls to inc(). Is this similar to closure in JS?
**Capture By reference**
auto inc_count(int x){
return [&x](){
return x++;
};
};
int main()
{
auto inc = inc_count(4);
cout<<inc()<<endl; //32765
cout<<inc()<<endl; //32765
cout<<inc()<<endl; //32765
cout<<inc()<<endl; //32765
return 0;
}
**Capture by value**
auto inc_count(int x){
return [x]()mutable{
return x++;
};
};
int main()
{
auto inc = inc_count(4);
cout<<inc()<<endl; //4
cout<<inc()<<endl; //5
cout<<inc()<<endl; //6
cout<<inc()<<endl; //7
return 0;
}
Actual Output :
32765
32765
32765
32765
Expected Output :
4
5
6
7
Upvotes: 1
Views: 2005
Reputation: 597
In this function, you receive x
as a copy of some argument.
auto inc_count(int x){
return [&x](){
return x++;
};
};
When you return from inc_count
, the x
being referenced by your returned value, &x
, is destroyed. This is why your value is close to the maximum short
value, 32,767. The memory at the address you are attempting to access has been freed and no longer contains any data structure.
Your pass by value works because the memory is not being freed. You are passing a copy of your data at each point; the program is not freeing this data and you end up with a coherent value.
Upvotes: 0
Reputation: 206567
In the first version, you are capturing a reference to a variable that is not alive after the function returns. You have a dangling reference after the function returns and your code has undefined behavior.
You can use the following to capture by reference.
auto inc_count(int& x){
return [&x](){
return x++;
};
};
But then, you can't use int_count(4)
in main
. You'll have to use a variable whose reference can be used in int_count
.
int main()
{
int number = 4;
auto inc = inc_count(number);
...
return 0;
}
Upvotes: 6