简体   繁体   中英

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?
}

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM