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:
Thanks
By default, variables are captured by const value . This means when the lambda is created, the lambda captures a constant copy of the outer scope variable, which means that the lambda is not allowed to modify them. In the following example, we capture the variable ammo and try to decrement it.
The capture list defines the outside variables that are accessible from within the lambda function body. The only capture defaults are. & (implicitly capture the used automatic variables by reference) and. = (implicitly capture the used automatic variables by copy).
The Captures Clause of the United States Constitution gives Congress the power to "make Rules concerning Captures on Land and Water." A variety of courts, scholars; politicians, and others have recently cited the Clause to support conflicting arguments about the scope of Congress's power to initiate and prosecute war.
The type of a lambda expression is unspecified. But they are generally mere syntactic sugar for functors. A lambda is translated directly into a functor.
The first captures the local variable x
by value; so it prints 1
both times, since its copy hasn't changed.
The second captures the local quasi-variable this
, not the member variable x
. So the body is equivialent to printf("%d\n", this->x);
, and will print the new value of 2
after you change x
.
If you were to explicitly capture x
(i.e. [x](){...}
), then you will see the same result as the first.
Is this the desired behaviour?
It's the behaviour specified by the language standard.
if i used [&] instead of [=] in ClassA, would those lambdas be identical?
No, but both would produce the same output. The first would capture the local x
by reference, so you will see the change to it.
Is there some general rule as to when [=] actually makes copy?
Yes, it copies the variable when the lambda is created.
When exactly is the capturing of variables by lambdas supposed to happen?
When the lambda is created.
Can I force lambda to do a re-capture of variables?
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).
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