Search code examples
c++lambdaclosures

Why does my function which returns a lambda seem to be transformed into a function which turns an int?


Given the following function that returns a lambda

auto foo(int y) {
    return [=](int x) { return x + y; };
}

GCC and Clang produce the following assembly

foo(int):
    mov     eax, edi
    ret

which as far as I can tell is equivalent to this

int bar(int n) {
    return n;
}

Yet bar seems to function as expected.

auto fn = foo(2);
std::cout << fn(3); //prints 5

Solution

  • Remember that a closure type is a class type. Your function is similar to this:

    auto foo(int y) {
        // return [=](int x) { return x + y; };
        struct closure_type {
            int y;
            auto operator()(int x) const { return x + y; }
        };
        return closure_type{ y };
    }
    

    And, once the types are removed, there really is no difference between returning an int and returning a trivial struct with a single int data member.

    You would have the exact same experience with your int returning function if you changed the types:

    using closure_type = decltype(foo(int{}));
    auto fn = std::bit_cast<closure_type>(bar(2));
    std::cout << fn(3); //prints 5