递归调用包装函数时 lambda 函数的内部工作
Inner working of lambda functions when wrapper function is called recursively
考虑以下代码:
int foo() {
int lf = [/*captures*/]() {/*body*/};
if(/*some condition*/) { return /*value*/; }
foo(); //recursive call
}
现在,在这段代码中,每当递归调用函数 foo
时,foo
的 activation record
将被推入堆栈。我想知道的是,lambda 函数及其定义是否包含在记录中?嗯..this 没用
lambda 存储在 foo()
的局部变量中,所以是的。每次调用 foo()
都会实例化一个新的 lambda,直到 foo()
退出才会被销毁。
lambda 只是实现 operator()
的编译器定义类型的语法糖。因此,您的示例 大致 相当于:
struct functor{
/*captures*/
void operator()() const {/*body*/}
};
int foo() {
functor lf{/*captures*/};
if(/*some condition*/) { return /*value*/; }
foo(); //recursive call
}
首先:
int lf = [/*captures*/]() {/*body*/};
是错误的代码,应该是
// case 1. lambda is automatic
auto lf = [/*captures*/]() {/*body*/}; // closure object
或(前提是 lambda returns 与 int
兼容)
// case 2. lambda is temporary
int lf = [/*captures*/]() {/*body*/} (); /* calling object created */
lambda 表达式是一个 shorthand 符号,用于创建具有唯一 class 的对象
(非常简单,您必须查看标准或语言参考以获取完整描述):
class Closure {
/* members storing captured values or references */
public:
return-type operator( /* argument list*/ ) { /*body*/ };
}
在第一种情况下,lambda 将存储在堆栈中,在第二种情况下,它是一个临时对象。
所以带有捕获列表的 lambda 会存储这样的对象,即所有捕获的值正好在您指示它存储 lambda 对象的位置,在您的情况下它是自动存储(所谓的 "stack")。使用无捕获 lambda 与声明一个函数并使用指向它的指针没有什么不同,没有与之关联的存储并且它可以转换为函数指针。
考虑以下代码:
int foo() {
int lf = [/*captures*/]() {/*body*/};
if(/*some condition*/) { return /*value*/; }
foo(); //recursive call
}
现在,在这段代码中,每当递归调用函数 foo
时,foo
的 activation record
将被推入堆栈。我想知道的是,lambda 函数及其定义是否包含在记录中?嗯..this 没用
lambda 存储在 foo()
的局部变量中,所以是的。每次调用 foo()
都会实例化一个新的 lambda,直到 foo()
退出才会被销毁。
lambda 只是实现 operator()
的编译器定义类型的语法糖。因此,您的示例 大致 相当于:
struct functor{
/*captures*/
void operator()() const {/*body*/}
};
int foo() {
functor lf{/*captures*/};
if(/*some condition*/) { return /*value*/; }
foo(); //recursive call
}
首先:
int lf = [/*captures*/]() {/*body*/};
是错误的代码,应该是
// case 1. lambda is automatic
auto lf = [/*captures*/]() {/*body*/}; // closure object
或(前提是 lambda returns 与 int
兼容)
// case 2. lambda is temporary
int lf = [/*captures*/]() {/*body*/} (); /* calling object created */
lambda 表达式是一个 shorthand 符号,用于创建具有唯一 class 的对象 (非常简单,您必须查看标准或语言参考以获取完整描述):
class Closure {
/* members storing captured values or references */
public:
return-type operator( /* argument list*/ ) { /*body*/ };
}
在第一种情况下,lambda 将存储在堆栈中,在第二种情况下,它是一个临时对象。
所以带有捕获列表的 lambda 会存储这样的对象,即所有捕获的值正好在您指示它存储 lambda 对象的位置,在您的情况下它是自动存储(所谓的 "stack")。使用无捕获 lambda 与声明一个函数并使用指向它的指针没有什么不同,没有与之关联的存储并且它可以转换为函数指针。