gpt4 book ai didi

运行时的 C++ lambda 实现

转载 作者:塔克拉玛干 更新时间:2023-11-03 06:47:22 25 4
gpt4 key购买 nike

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

  1. NSGlobalBlock - 这是运行时的单例,它是在我们不使用堆栈变量值的情况下创建的。
  2. NSStackBlock - 这不是单例,它是在堆栈上分配的(而不是在堆上),它是在我们使用一些堆栈变量时创建的。
  3. NSMallocBlock - 在堆上分配,当我们想将 block 存储为 ivar 或某个类的属性或堆中的任何位置时使用。 @property (nonatomic, copy) MyBlockType myBlock; 或者当我们使用 Block_copy() 函数时。这非常重要,因为 NSMallocBlock 从上下文中保留对象,如果我们不正确使用 block ,这个事实会产生一些拥有循环。

所以,我的问题是:“我在哪里可以找到 C++ lambdas 运行时的完整解释,以及编译器如何处理它们?或者你能解释一下吗?使用 C++ lambdas 进行内存管理是否有任何具体问题?lambdas 在哪里分配,在堆上还是在堆栈上?”

最佳答案

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

标准没有指定它在内存方面的分配位置,但根据经验,它们大致相当于 old-school functors 并且它们和它们捕获的值被复制到堆栈上,就像任何普通对象一样。

例如

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

关于运行时的 C++ lambda 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20313847/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com