简体   繁体   中英

C++ lambda value can't capture

Here is my code,I want to test closure in c++ like javascript. Why the compiler yield this message? "testLambda.cpp: In lambda function: testLambda.cpp:8:11: error: 'a' is not captured"

    #include <iostream>
    #include <functional>
    std::function<bool(int)> returnLambda(int a){
        auto b  = 1;
        auto c  = 2;

        return [&](int x)
        {   return x*(b++)+c+a == 0;};
    }
    auto f = returnLambda(21);
    int main(){
        auto c = f(1);
        auto b = f(1);

        std::cout<<c<<b<<std::endl;
        return 0;
    }

You need to specify your captures in the square brackets, that's why lambdas require square brackets in the first place. You can capture them by reference:

[&a,&b,&c] (int x) ...

or by value:

[a,b,c] (int x) ...

or mix it up:

[a,&b,c] (int x) ...

Or you can just capture everything that you use:

[&] (int x) ... // by reference
[=] (int x) ... // by value

If you choose to capture a variable by value, but need to modify it, then you need to make it mutable:

[=] (int x) mutable ...

Benjamin Lindley provided an answer about declaration of lambdas in C++.

But technically speaking you cannot reproduce JavaScript closures using C++ lambdas.

In JS outer variables that used by local function are protected by GC mechanism.

But in C++, if you capture variables by reference, you can easily get into situation when referenced variables are destroyed and you'll get segmentation fault / access violation.

This, for example:

#include <iostream>
#include <functional>
std::function<bool(int)> returnLambda(int a){
    auto b  = 1;
    auto c  = 2;

    return [&](int x)
    {   return x*(b++)+c == 0;};
}
auto f = returnLambda(21);
int main(){
    auto c = f(1);
    auto b = f(1);

    std::cout<<c<<b<<std::endl;
    return 0;
}

will crash badly as after return from the returnLambda() its variables a,b and c are destroyed (their stack location is used by something else) when function f() is called.

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