0

考虑以下代码:

int foo() {
    int lf = [/*captures*/]() {/*body*/};
    if(/*some condition*/) { return /*value*/; }
    foo();    //recursive call
}

现在,在这段代码中,每当foo递归调用函数时,都会将一个activation recordoffoo 压入堆栈。我想知道的是,记录中是否包含 lambda 函数及其定义?嗯..没有帮助

4

2 回答 2

2

lambda 存储在 的局部变量中foo(),所以是的。每次调用都会foo()实例化一个新的 lambda,该 lambda 在foo()退出之前不会被销毁。

lambda 只是实现的编译器定义类型的语法糖operator()。所以你的例子大致相当于这个:

struct functor{
    /*captures*/
    void operator()() const {/*body*/}
};

int foo() {
    functor lf{/*captures*/};
    if(/*some condition*/) { return /*value*/; }
    foo(); //recursive call
}
于 2020-03-25T07:56:33.260 回答
1

首先:

int lf = [/*captures*/]() {/*body*/};

代码不正确,应该是

// case 1. lambda is automatic
auto lf = [/*captures*/]() {/*body*/}; // closure object

或(前提是 lambda 返回与 兼容的内容int

// case 2. lambda is temporary
int lf = [/*captures*/]() {/*body*/} (); /* calling object created */

lambda 表达式是创建具有唯一类的对象的简写符号(非常简化,您必须查看标准或语言参考以获得完整描述):

class Closure {
    /* members storing captured values or references */ 
public:
    return-type  operator( /* argument list*/ ) { /*body*/ };
}

在第一种情况下,lambda 将存储在堆栈中,在第二种情况下,它是一个临时对象。

因此,带有捕获列表的 lambda 将存储此类对象,即所有捕获的值恰好在您指示它存储 lambda 对象的位置,在您的情况下,它是自动存储(所谓的“堆栈”)。使用无捕获 lambda 与声明一个函数并使用指向它的指针没有什么不同,没有与之关联的存储,它可以转换为函数指针。

于 2020-03-25T08:07:49.110 回答