How to Implement a Closure

I need help by implementing a Closure example.

Here is my code so far:

1
2
3
4
5
6
7
8
9
10
11
12
13
auto fnc()
{
    int x = 0;
    auto clos = [&]() { return ++x; };
    return clos;
}

#include <iostream>
int main()
{
    auto clos = fnc();
    for (int i=0; i<5; ++i) std::cout << clos() << '\n';
}

This seems work only if var x would be static. But I thought that for a closure the variables needn't to be static.
Another question is: What would the type of such a lambda function be (so when I would replace all 'auto')?

Thanks
> This seems work only if var x would be static.
> But I thought that for a closure the variables needn't to be static.

In the example, x is captured by reference; the closure object does not hold a copy of x.

A closure where the variable is captured by value can be safely returned, even if the variable is not static.
For example,
1
2
3
4
5
6
auto fnc()
{
    int x = 0;
    const auto clos = [x]() { return x+1; };
    return clos;
}



> What would the type of such a lambda function be (so when I would replace all 'auto')?

The precise type of the closure object is left to the implementation; to get a portable type for the callable object, wrap the closure in a call wrapper. http://en.cppreference.com/w/cpp/utility/functional/function

1
2
3
4
5
6
std::function< int() > fnc()
{
    int x = 0;
    const std::function< int() > fn = [x]() { return x+1; };
    return fn ;
}

or, simply:
1
2
3
4
5
std::function< int() > fnc()
{
    int x = 0;
    return [x]() { return x+1; } ;
}
You're capturing by reference (the [&] bit), and that does not extend the lifetime of the captured variable. The closure object is returned from fnc, while x is destroyed, and so the closure is holding a dangling reference.
Either capture by value auto clos = [=]() mutable { return ++x; }; or make sure the lifetime of x encloses the lifetime of the closure object (making x static is the ultimate way to do that)

What would the type of such a lambda function be (so when I would replace all 'auto')?

each lambda expression produces a result of a unique type, which cannot be named. It can be deduced with auto, or wrapped in std::function

Last edited on
Topic archived. No new replies allowed.