【发布时间】:2016-12-26 05:46:30
【问题描述】:
总结
在 C++ 中,当我从一个捕获该函数本地变量的函数返回一个 lambda 时,具体会发生什么,为什么?编译器 (g++) 似乎允许这样做,但它给我的结果与我预期的不同,所以我不确定这在技术上是否安全/受支持。
详情
在某些语言(Swift、Lisp 等)中,您可以在闭包/lambda 中捕获局部变量,只要闭包在范围内(我听说它称为“lambda over在 Lisp 上下文中放弃 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,已修复,对此感到抱歉。
-
在第一种情况下,您只是引用了堆栈上的一些随机内存。