My real understanding is that a lambda without a captured closure exactly resembles a C callback. However, when the environment is captured either by value or by reference, an anonymous object is created on the stack.
No; it is always a C ++ object with an unknown type created on the stack. Without a capture, a lambda can be converted to a pointer to a function (although it is suitable for C calling conventions, it depends on the implementation), but this does not mean that it is a pointer to a function.
When a closure value is to be returned from a function, one wraps it in std :: function. What happens to closure memory in this case?
A lambda is not something special in C ++ 11. It is an object, like any other object. The lambda expression leads to a temporary one, which can be used to initialize the variable on the stack:
auto lamb = []() {return 5;};
lamb is the stack object. It has a constructor and a destructor. And for this, he will follow all the rules of C ++. The lamb type will contain the values ββ/ references to be captured; they will be members of this object, like any other objects of any other type.
You can pass it to std::function :
auto func_lamb = std::function<int()>(lamb);
In this case, it will get a copy of the lamb value. If lamb captured something by value, there would be two copies of these values; one in lamb and one in func_lamb .
When the current scope expires, func_lamb will be destroyed and then lamb , according to the rules for clearing stack variables.
You can just as easily allocate one on the heap:
auto func_lamb_ptr = new std::function<int()>(lamb);
Exactly where the memory for the contents of std::function goes depends on the implementation, but the type erasure used by std::function usually requires at least one memory allocation. This is why the std::function constructor can take a dispenser.
It is freed whenever the std :: function is freed, i.e. Does it refer to std :: shared_ptr?
std::function is a copy of its contents. Like almost every standard C ++ library type, function uses value semantics. Thus, it can be copied; when copying, the new function object is completely split. It can also be moved, so any internal distributions can be transferred accordingly, without requiring more selection and copying.
Thus, there is no need for reference counting.
Everything else that you state is correct if you assume that "memory allocation" corresponds to "poor use in real time."