63

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++?

Matthias Braun
  • 32,039
  • 22
  • 142
  • 171
Parvinder Singh
  • 1,737
  • 2
  • 12
  • 17
  • 3
    Besides the answer below, also check http://en.cppreference.com/w/cpp/language/lambda for more of a reference page. – Some programmer dude Sep 28 '12 at 07:11
  • 2
    Apparently lots of people still mix anonymous functions with closures. It is still not clear for me if C++11 indeed supports closures, or just anonymous functions ("lambdas"). I would _not_ expect C++ to support actual closures in the same sense as in JavaScript, Python, Scala and others, would find it very surprising. – dividebyzero Mar 01 '17 at 10:33
  • 1
    Proving myself wrong, yeah, it captures variables in context, by copy and even by reference apparently, the only quirk is that there is no garbage collection... Still would like to better understand how that all works in practice http://en.cppreference.com/w/cpp/language/lambda – dividebyzero Mar 01 '17 at 10:39
  • http://scottmeyers.blogspot.nl/2013/05/lambdas-vs-closures.html – dividebyzero Mar 01 '17 at 10:52

7 Answers7

43

The latest C++ standard, C++11, has closures.

http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions

http://www.cprogramming.com/c++11/c++11-lambda-closures.html

ArthurChamz
  • 2,039
  • 14
  • 25
Apeirogon Prime
  • 1,218
  • 13
  • 25
  • 8
    No we don't. In C++, all closures are member functions of a hidden class that gets passed around. And because a class gets passed around, the function singnatures are incompatible. Yes, we kinda have closures, but they are NOT actual closures, they are NOT a function that has access to some other functions variables, that gets allocated and whose address can be passed around. Neither with bind, nor with lambda-expressions. And Visual Studio/VisualCPP doesn't support alloc_callback, which is used in C to do this. And you can't pass a member function to a function that expects a static function. – Stefan Steiger Mar 27 '19 at 09:27
  • 3
    @StefanSteiger I guess Rust closures aren't actual closures either then? They're exactly like that. Do the C++11 implement some interface so they can be called dynamically, similarly to `dyn Fn(x) -> y` in Rust? – Mihail Malostanidis May 11 '22 at 16:33
24

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).

nz_21
  • 6,140
  • 7
  • 34
  • 80
Zrin
  • 919
  • 15
  • 25
  • 12
    The behavior is similar to a closure but I would not say it is a closure. – Setepenre Nov 11 '15 at 14:45
  • 2
    @Stepenre what would be the difference? – Zrin Nov 12 '15 at 07:15
  • 6
    This hardly looks like a closure, what you have here is just an object holding a state modified by a method, plus some syntactic sugar due to the fact it is "operator()" instead of any other method. Make it return a lambda that depends on the state, or on a parameter of the method, and then we are talking. – dividebyzero Mar 01 '17 at 10:21
  • 4
    @dividebyzero One thing is the abstract idea of a closure, another thing is how you use that idea in a programming language. In the examples above, both "my_add_3_closure" and "adder" are closures - they match the definition. The objects here is effectively a references to a function... I want to underline that the idea of closures was used in C++ programming long before C++11 and that the new lambda construct just makes it easier. – Zrin Mar 01 '17 at 11:53
  • @Zrin I'd like to comment that other instances of `summer` will have access to each other's private `sum` variable, as access keywords in C++ are per-class, not per-instance. Because of this I'd argue it is not a closure (as encapsulation is a property many people expect). Lambdas on the other hand do not break this encapsulation, as each has a unique type. – Anthony May 07 '19 at 01:07
  • 2
    @AnthonyMonterrosa, you're making a mistake in your argument. `private: int sum` means the member can be accessed only by member functions, but it still belongs to the instance, not to the class. `static int sum` would belong to the class. – Zrin May 23 '19 at 08:10
  • @Zrin. Consider the following code. Running it will show what I mean (and sorry, the formatting in a comment will be terrible I'm sure): ```class X { int x; public: X(int x): x(x) { } int getX(const X& instance) const { return instance.x; } void setX(X& instance, const int newX) { instance.x = newX; } }; int main() { X a(0); X b(1); // Read access std::cout << a.getX(b) << std::endl; // Write access a.setX(b, 2); std::cout << b.getX(b) << std::endl; }``` – Anthony May 26 '19 at 02:07
  • @Zrin as you can see, if you run that snippet in [this online compiler](https://www.onlinegdb.com/online_c++_compiler), that a's instance methods can manipulate b's private members. `public`, `private`, and `protected` are compile-time guarantees and are on a per-class basis, not per-instance. – Anthony May 26 '19 at 02:08
  • 1
    @AnthonyMonterrosa, your critique of the examples I've given in the answer above is that the closure's context is not hidden well enough, because there is nothing that would stop an ignorant programmer to deliberately and obviously break the concept. But if the creator doesn't want a closure, then why bother anyway? – Zrin Jun 12 '19 at 06:29
  • @Zrin I was just pointing out a technical detail. Functionally it's good enough. – Anthony Jun 12 '19 at 17:05
  • 1
    For anyone who thinks this isn't a closure. Functionally, this is definitely a closure. It might not look like a closure compared to one's personal experience. But the visual looks of what one considers a closure is entirely a personal opinion and isn't really definable. At the end of the day, all that really matters if the functionality. – David Callanan Aug 19 '21 at 13:39
22

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
}
einpoklum
  • 118,144
  • 57
  • 340
  • 684
Setepenre
  • 1,883
  • 3
  • 13
  • 16
  • 1
    To be really sure, it would be nice to see what happens if you run `my_f()` again after `my_f1()`, because it might still be the same variable that you have just directly assigned with the call to `make_my_closure`. – dividebyzero Mar 01 '17 at 10:28
  • 1
    `x` is a temporary value in `make_my_closure`. So IMO it would not make sense. I added the case you asked. Which behave as expected – Setepenre Mar 03 '17 at 16:21
9

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).

James Kanze
  • 150,581
  • 18
  • 184
  • 329
7

Yes, C++11 has closures named lambdas.

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

Rost
  • 8,779
  • 28
  • 50
0

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)))))
Mark Yang
  • 226
  • 3
  • 16
0

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;
}
Amresh Kumar
  • 158
  • 2
  • 8