【发布时间】:2011-12-19 04:13:24
【问题描述】:
我一直在尝试 C++11 中的一些新功能,并尝试编写以下程序,但希望它不起作用。令我惊讶的是,它确实如此(在带有 'std=c++0x' 标志的 Linux x86 上的 GCC 4.6.1 上):
#include <functional>
#include <iostream>
#include <memory>
std::function<int()> count_up_in_2s(const int from) {
std::shared_ptr<int> from_ref(new int(from));
return [from_ref]() { return *from_ref += 2; };
}
int main() {
auto iter_1 = count_up_in_2s(5);
auto iter_2 = count_up_in_2s(10);
for (size_t i = 1; i <= 10; i++)
std::cout << iter_1() << '\t' << iter_2() << '\n'
;
}
我期望在每次执行返回的 lambda 时删除“from_ref”。这是我的推理:一旦 count_up_in_2s 运行,from_ref 就会从堆栈中弹出,但是由于返回的 lambda 不一定立即运行,因为它已返回,所以在短时间内不存在另一个引用,直到相同的引用被当 lambda 实际运行时被推回,所以 shared_ptr 的引用计数不应该为零然后删除数据吗?
除非 C++11 的 lambda 捕获比我认为的要聪明得多,否则我会很高兴。如果是这种情况,我是否可以假设只要 /something/ 处理动态分配的内存,C++11 的变量捕获将允许所有的词法作用域/闭包技巧,就像 Lisp 一样?我是否可以假设所有捕获的引用都将保持活动状态,直到 lambda 本身被删除,从而允许我以上述方式使用 smart_ptrs?
如果这是我想的那样,这是否意味着 C++11 允许表达性的高阶编程?如果是这样,我认为 C++11 委员会做得很好 =)
【问题讨论】:
标签: c++ variables memory-management lambda c++11