运行时的C ++ lambda实现

时间:2013-12-01 15:35:02

标签: c++ objective-c lambda objective-c-blocks objective-c++

在Objective-C中,我们知道块在运行时有3个实现。

  1. NSGlobalBlock - 在运行时是单例,并且在我们不使用堆栈变量值的情况下创建它。
  2. NSStackBlock - 这不是单例,它是在堆栈上分配的(不在堆上),它是在我们使用一些堆栈变量时创建的。
  3. NSMallocBlock - 在堆上分配,当我们想要将块存储为某些类的ivar或属性或堆f.e中的任何位置时使用。 @property (nonatomic, copy) MyBlockType myBlock;或我们使用Block_copy()函数时。这非常重要,因为NSMallocBlock保留了来自上下文的对象,如果我们不使用正确的块,这个事实可以创建一些拥有周期。
  4. 所以,我的问题是:“我在哪里可以找到C ++ lambdas运行时的完整解释,以及它们如何被Compiler处理?或者你可以解释一下吗?使用C ++ lambdas进行内存管理是否有任何特定问题?lambdas是什么?在堆上或堆栈上分配?“

1 个答案:

答案 0 :(得分:2)

Lambdas实现是特定于编译器的。

标准没有指定内存分配的位置,但作为经验法则,它们大致相当于old-school functors ,并且它们及其捕获的值被复制到堆栈,就像任何普通对象一样。

E.g。

std::vector<int> v{10,11,12,13};
std::for_each(v.begin(), v.end(), [](int& i) {i++;});

只是一种无国籍的功能。

或者,

std::vector<int> v{10,11,12,13};
int C = 10;
int D = 20;
std::for_each(v.begin(), v.end(), [C,&D](int& i) {i += C + D;});

等同于在堆栈上构建的仿函数,其副本为C,并且D作为其成员的引用(但可能会被优化掉)。

你真正将一个lambda对象放在堆上的唯一一次是它转换为std::function时,它的完成方式取决于编译器对std::function的实现。

void g(const std::function& f);
// ...
auto f = [=](int& i){i += C;}; // still on the stack (compiler-specific type)
g(f); // std::function constructed, possibly on the heap