Do we have closures in C++?

59.8k views Asked by At

I was reading about closures on the net. I was wondering if C++ has a built-in facility for closures or if there is any way we can implement closures in C++?

7

There are 7 answers

2
Apeirogon Prime On BEST ANSWER
0
Rost On

Yes, C++11 has closures named lambdas.

In C++03 there is no built-in support for lambdas, but there is Boost.Lambda implementation.

0
James Kanze On

I suspect that it depends on what you mean by closure. The meaning I've always used implies garbage collection of some sort (although I think it could be implemented using reference counting); unlike lambdas in other languages, which capture references and keep the referenced object alive, C++ lambdas either capture a value, or the object refered to is not kept alive (and the reference can easily dangle).

11
Zrin On

If you understand closure as a reference to a function that has an embedded, persistent, hidden and unseparable context (memory, state), then yes:

class add_offset {
private:
    int offset;
public:
    add_offset(int _offset) : offset(_offset) {}
    int operator () (int x) { return x + offset; }
}

// make a closure
add_offset my_add_3_closure(3);

// use closure
int x = 4;
int y = my_add_3_closure(x);
std::cout << y << std::endl;

The next one modifies its state:

class summer
{
private:
    int sum;
public:
    summer() : sum(0) {}
    int operator () (int x) { return sum += x; }
}

// make a closure
summer adder;
// use closure
adder(3);
adder(4);
std::cout << adder(0) << std::endl;

The inner state can not be referenced (accessed) from outside.

Depending on how you define it, a closure can contain a reference to more than one function or, two closures can share the same context, i.e. two functions can share the same persistent state.

Closure means not containing free variables - it is comparable to a class with only private attributes and only public method(s).

2
Setepenre On

Yes, This shows how you could implement a function with a state without using a functor.

#include <iostream>
#include <functional>
 
std::function<int()> make_my_closure(int x) {
    return [x]() mutable {   
        ++x;
        return x;   
    };
}

int main()  {
    auto my_f = make_my_closure(10);
    
    std::cout << my_f() << std::endl; // 11
    std::cout << my_f() << std::endl; // 12
    std::cout << my_f() << std::endl; // 13
    
     auto my_f1 = make_my_closure(1);

    std::cout << my_f1() << std::endl; // 2
    std::cout << my_f1() << std::endl; // 3
    std::cout << my_f1() << std::endl; // 4

    std::cout << my_f() << std::endl; // 14
}
0
Mark Yang On

Strictly speaking. 'Closure' is LISP only. Use Let returns lambda as last commands. 'Let Over Lambda'. This is possible only for LISP because of infinite scope with lexical scoping. I don't know any other language support this natively until know.

(defun my-closure ()
   (let ((cnt 0))
      (lambda () 
         (format t "called : ~A times" (incf cnt)))))
0
Amresh Kumar On

You can achive similar functionality using static variables and lambdas.

#include <iostream>
#include<functional>

int main()
{
    std::function<std::function<int()>()> generator_function=[]()->std::function<int()>{
        static int i=0;
        return [&]()->int{
            return i++;
        };
    };
    
    std::function<int()> iterator_function=generator_function();
    
    std::cout<<iterator_function()<<std::endl;  //1
    std::cout<<iterator_function()<<std::endl;  //2
    std::cout<<iterator_function()<<std::endl;  //3 
    std::cout<<iterator_function()<<std::endl;  //4
    return 0;
}