You are not logged in.
Pages: 1
Hi,
I am not a C++ programmer; I just caught a rumor about closures having been added to the language. So far as I know there's still no garbage collection in C++.
My question: how can one implement closures without garbage collection?
Offline
It is not a rumour... This might not be the most technical explanation but here goes. Closures can exist with manual memory management. This happens in C++. C++ lambdas can take in variables by value or by reference and the lifetime of the variables are managed by the user. Take a look at https://en.wikipedia.org/wiki/Closure_( … and_theory and https://en.wikipedia.org/wiki/Anonymous … 2B.2B11.29
Hopefully someone can chime in with a better explanation.
Offline
Hi Llama,
C++ closures begin their lives on the stack. Most are short-lived, and are never copied onto the heap.
C++ supports dynamically allocated closures through std::function (n.b: std::function does _not_ always perform heap-allocation!). Thankfully, std::function uses std::unique_ptr to manage the memory allocated to store the closure. That means the closure is destroyed whenever the std::function goes out of scope, or when its owner is destroyed, etc.
If you'd like to learn more about this, I'd suggest reading:
1) http://en.cppreference.com/w/cpp/language/lambda
This will show you how to create closures using pass-by-value and/or pass-by-reference semantics. It should also explain that C++ lambdas are just syntactic sugar for initializing functor structs, i.e structures containing a function pointer and the closure state. No dynamic allocation happens at this level.
2) http://en.cppreference.com/w/cpp/utilit … n/function
This explains how function pointers, lambdas, and member functions can all be used with a common interface: std::function. Dynamic allocation may occur here, but as I mentioned earlier, it is managed automatically (without any kind of GC).
Finally: eagle-eyed readers will note that I've taken some liberties while describing how the STL and the compiler come together to support closures. Please keep in mind the standard disclaimers about each compiler/compiler runtime being different, and about listening to strangers .
Offline
Closures are instantiations of an anonymous class. Thus, writing
int a, b;
auto test = [a, &b] (int c) -> bool {
[...]
};
is very similar to writing
class AnonymousClosureType {
public:
AnonymousClosureType(int _a, int& _b)
: a(_a), b(_b) { }
inline bool operator () (int c) const {
[...]
}
private:
int a;
int& b;
};
// ...
int a, b;
auto test = AnonymousClosureType(a, b);
It behaves the same in terms of memory management.
Last edited by VikingGe (2015-12-16 23:05:28)
Offline
Pages: 1