简介
在C++中,当我从一个函数返回一个捕获了该函数的局部变量的lambda时,具体会发生什么以及为什么?编译器(g ++)似乎允许它,但它给了我不同于我预期的结果,所以我不确定这是否在技术上是安全/支持的。
细节
在一些语言(Swift,Lisp等)中,您可以在闭包/lambda中捕获局部变量,并且只要闭包在范围内,它们就保持有效并在范围内(我听说过在Lisp上下文中称之为“lambda over let over lambda”)。例如,在Swift中,我尝试做的示例代码是:
func counter(initial: Int) -> (() -> Int) {
var count = initial
return { count += 1; return count }
}
let c = counter(initial: 0)
c() // returns 1
c() // returns 2
c() // returns 3
我尝试编写了以下C++代码,与此相似:
auto counter(int initial)
{
int count = initial;
return [&count] () -> int {
count = count + 1;
return count;
};
}
然而,我得到的结果是:
auto c = counter(0);
std::cout << c() << std::endl; // prints 1
std::cout << c() << std::endl; // prints 1
std::cout << c() << std::endl; // prints 1
如果我捕获了一个仍在作用域内的变量,它将按照我预期的方式工作。例如,如果我在单个函数中执行以下所有操作:
int count = 0;
auto c = [&count] () -> int {
count = count + 1;
return count;
};
std::cout << c() << std::endl; // prints 1
std::cout << c() << std::endl; // prints 2
std::cout << c() << std::endl; // prints 3
所以我猜我的问题是,在上面的第一个C++示例中,实际捕获了什么?这是定义行为还是只有对堆栈上某些随机内存的引用?
auto c = counter();
。你怎么可以在没有参数的情况下调用函数呢?似乎这甚至无法编译。 - Richard