我目前的理解是,没有捕获闭包的 lambda 与 C 回调完全相同。但是,当通过值或引用捕获环境时,会在堆栈上创建一个匿名对象。
不;这是always在堆栈上创建的未知类型的 C++ 对象。无捕获 lambda 可以是转换的到函数指针中(尽管它是否适合 C 调用约定取决于实现),但这并不意味着它is函数指针。
当必须从函数返回值闭包时,可以将其包装在 std::function 中。在这种情况下,闭包内存会发生什么情况?
lambda 在 C++11 中没有什么特别的。它是一个像任何其他对象一样的对象。 lambda 表达式会产生一个临时值,可用于初始化堆栈上的变量:
auto lamb = []() {return 5;};
lamb
是一个堆栈对象。它有一个构造函数和析构函数。它将遵循所有 C++ 规则。的类型lamb
将包含捕获的值/引用;它们将是该对象的成员,就像任何其他类型的任何其他对象成员一样。
您可以将其交给std::function
:
auto func_lamb = std::function<int()>(lamb);
在这种情况下,它将得到一个copy的价值lamb
. If lamb
按价值捕获任何东西,就会有这些价值的两个副本;一进lamb
,以及其中一func_lamb
.
当当前范围结束时,func_lamb
将被摧毁,随后lamb
,按照清理堆栈变量的规则。
您可以轻松地在堆上分配一个:
auto func_lamb_ptr = new std::function<int()>(lamb);
a 的内容的内存到底在哪里std::function
go 是依赖于实现的,但是所采用的类型擦除std::function
通常需要至少一次内存分配。这就是为什么std::function
的构造函数可以采用分配器。
每当 std::function 被释放时它是否被释放,即它是否像 std::shared_ptr 一样进行引用计数?
std::function
存储一个copy其内容。就像几乎所有标准库 C++ 类型一样,function
uses 值语义。因此,它是可复制的;当它被复制时,新的function
对象是完全独立的。它也是可移动的,因此任何内部分配都可以适当地转移,而不需要更多的分配和复制。
因此不需要引用计数。
您所说的其他所有内容都是正确的,假设“内存分配”等于“在实时代码中使用不好”。