Okay, so this is right off the bat from [expr.prim.lambda]p16 in n3337.pdf. Below code is given as an example:
int a = 1, b = 1, c = 1;
auto m1 = [a, &b, &c]() mutable
{
auto m2 = [a, b, &c]() mutable
{
std::cout << a << b << c; // Shouldn't this print 113 or 133?
a = 4; b = 4; c = 4;
};
a = 3; b = 3; c = 3;
m2();
};
a = 2; b = 2; c = 2;
m1();
std::cout << a << b << c; // Okay, this prints 234
and that it shall generate below output:
123234
However, the way I have understood the text in [expr.prim.lambda] (which is somehow obviously flawed), I feel the output should be 113234
, specifically the value of b
printed in m2
. Below is my understanding/explanation:
When std::cout << a << b << c;
is executed inside m2
, as per [expr.prim.lambda]p16 (emphasis mine):
If a lambda-expression m2 captures an entity and that entity is captured by an immediately enclosing lambda expression m1, then m2’s capture is transformed as follows:
— if m1 captures the entity by copy, m2 captures the corresponding non-static data member of m1’s closure type;
Therefore, the a
inside m2
shall capture the member generated to the corresponding a
captured in the closure type m1
. Since, a
in m1
captures by copy, therefore a
's value in m2
should be 1
.
The standard goes on to say (again, emphasis mine):
— if m1 captures the entity by reference, m2 captures the same entity captured by m1.
I believe "same entity" here refers to the entity captured by m1
via reference and that m2
shall also be a reference to the same entity if it's a capture by reference, or a copy of it if it's a capture by copy.
Therefore for b
in m2
shall refer to the b
defined outside both lambdas. The value of b
in m2
then should be 1
as this should be equivalent to capture by copy.
Where am I going wrong? More specifically, when is b
inside m2
initialised?
Aucun commentaire:
Enregistrer un commentaire