gmmo
gmmo

Reputation: 2791

lambda function c++ capture by value reset its values, why?

Can someone explain me why localVar after being incremented by 1 is reset back to 10? Looks like the lambdas make copies of the capture-by-value on the stack before executing them.

void lambdaTest()
{
    int localVar = 10;

    // Access all local variables by reference
    auto byRef = [&] ()
    {
        cout << "localVar = " << ++localVar << endl;
    };

    // Access all local variables by value
    auto byValue = [=] () mutable 
    {
        cout << "localVar = " << localVar << endl;
    };


    byRef();        // localVar = 11
    byValue();      // localVar = 10, why?
}

Upvotes: 3

Views: 504

Answers (2)

Brian Rodriguez
Brian Rodriguez

Reputation: 4359

Yes, that's exactly what they do.

Lambdas, internally, are structs with an operator() set up for you. When you ask a lambda to capture-by-value, the struct stores a copy of any local variables that are referenced as members of the struct. Thus, what you're seeing isn't localVar being reset, you're seeing the lambda's copy of localVar.

Here's an example that illustrates this behavior:

#include <iostream>
#include <assert.h>

int main()
{
    int localVar = 10;
    auto byRef = [&]() {
        std::cout << "byRef = " << ++localVar << '\n';
    };
    auto byValue = [=]() mutable {
        // `mutable` lets us make changes to the *copy* of `localVar`
        std::cout << "byVal = " << localVar++ << '\n';
    };
    byRef();   // byRef = 11  -> actual localVar is now 11
    byRef();   // byRef = 12  -> actual localVar is now 12
    byRef();   // byRef = 13  -> actual localVar is now 13
    byValue(); // byVal = 10  -> copied localVar is now 11
    byValue(); // byVal = 11  -> copied localVar is now 12
    assert(localVar == 13);
}

Demo

Upvotes: 3

Nks Sai
Nks Sai

Reputation: 23

just add another output.

void lambdaTest()
{
    int localVar = 10;

    // Access all local variables by reference
    auto byRef = [&] ()
    {
        cout << "localVar = " << ++localVar << endl;
    };

    // Access all local variables by value
    auto byValue = [=] () mutable
    {
        cout << "localVar = " << localVar << endl;
    };


    byRef();        // localVar = 11
    byValue();      // localVar = 10
    cout <<localVar << endl; // localVar = 11
}

c++ 11 capture-by-value capture values when lambda is defined.so, lambda haven't change value outside.

Upvotes: 0

Related Questions