Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Figuring out why capturing by reference in a nested lambda produces a weird result

When the outer variable x is captured by value

return [=](int y){ return x * y; };

foo(2)(3) produces 6.

However if I capture x by reference

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

return [&](int y){ return x * y; };

foo(2)(3) produces 9.

Minimal Code

#include <iostream>
#include <functional>

int main()
{
    using namespace std;
    function<function<int(int)>(int)> foo = [](int x)
    {
        return [&](int y) { return x * y; };
    };
    cout << foo(2)(3);
    return 0;
}

Question

I cannot figure out why this happens, can you?

>Solution :

x is local to the outer function, so it’s destroyed as soon as that function returns.

Consider a simpler example.

#include <iostream>
#include <functional>

int& foo(int x) {
    return x;
}

int main()
{
    using namespace std;
    int& b = foo(5);
    return 0;
}

Here it’s easier to see that b is a dangling reference.

Next we go ahead and instead of returning the reference directly, we return a lambda that captures the variable by reference.

#include <iostream>
#include <functional>

auto foo(int x) {
    return [&x]() {return x;};
}

int main()
{
    using namespace std;
    auto b = foo(5);
    return 0;
}

The problem still remains. Once the lambda is returned, x has already gone out of scope and is no longer alive. But the lambda holds a (dangling) reference to it.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading