I have trouble understanding lambda functions and the mechanism to capture variables, so I did a little testing and arrived at really weird conclusion. that is:
class ClassA
{
public:
std::function<void()> lambda;
void DoYourStuff()
{
int x;
x = 1;
lambda = [=] () { printf("A %d\n", x);};
lambda();
x = 2;
lambda();
}
};
class ClassB
{
public:
std::function<void()> lambda;
int x;
void DoYourStuff()
{
x = 1;
lambda = [=] () { printf("B %d\n", x);};
lambda();
x = 2;
lambda();
}
};
Note: only difference is in placement of x variable;
ClassA and ClassB’s functions have different output!
A 1
A 1
B 1
B 2
So my questions are:
- Is this the desired behaviour?
- if i used [&] instead of [=] in ClassA, would those lambdas be identical?
- Is there some general rule as to when [=] actually makes copy?
- When exactly is the capturing of variables by lambdas supposed to happen?
- Can I force lambda to do a re-capture of variables?
Thanks
The first captures the local variable
xby value; so it prints1both times, since its copy hasn’t changed.The second captures the local quasi-variable
this, not the member variablex. So the body is equivialent toprintf("%d\n", this->x);, and will print the new value of2after you changex.If you were to explicitly capture
x(i.e.[x](){...}), then you will see the same result as the first.It’s the behaviour specified by the language standard.
No, but both would produce the same output. The first would capture the local
xby reference, so you will see the change to it.Yes, it copies the variable when the lambda is created.
When the lambda is created.
No. Once it’s captured by value, it has its own copy of the variable, with no way to access the original. If you need to see changes to the original, then capture by reference (and take care with object lifetimes).