C++ Lambdas,捕获,智能Ptrs和堆栈:为什么这有效?

Lou*_*uis 8 c++ variables lambda memory-management c++11

我一直在玩C++ 11中的一些新功能,我试着编写以下程序,期望它不起作用.令我惊讶的是,它(在Linux x86上的GCC 4.6.1上带有'std = c ++ 0x'标志):

#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'
        ;
}
Run Code Online (Sandbox Code Playgroud)

我希望每次执行返回的lambda时都会删除'from_ref'.这是我的推理:一旦运行count_up_in_2s,from_ref就会从堆栈中弹出,但由于返回的lambda不是必须立即运行,因为它已经返回,所以在相同的引用之前,没有另一个引用存在很短的时间当lambda实际运行时推回,所以shared_ptr的引用计数不应该为零,然后删除数据?

除非C++ 11的lambda捕获比我给它的功能更加聪明,如果是的话,我会很高兴的.如果是这种情况,我可以假设C++ 11的变量捕获将允许所有词法范围/闭包技巧la Lisp,只要/ something /正在处理动态分配的内存吗?我可以假设所有捕获的引用都将保留,直到lambda本身被删除,允许我以上述方式使用smart_ptrs吗?

如果这是我认为的那样,这是不是意味着C++ 11允许表达高阶编程?如果是这样,我认为C++ 11委员会做得很好=)

Set*_*gie 7

lambda from_ref按值捕获,因此它会复制.由于这个副本,当from_ref被破坏时引用计数不为0 ,因为lambda中仍然存在副本,所以它是1.

  • @Louis不,不是`function`对象,而是lambda.`std :: function`不知道lambdas的捕获. (3认同)
  • @Louis - 捕获的变量存储为编译器生成的lambda对象的成员变量.每个lambda表达式都会生成一个自定义类,它将捕获存储为成员(通过引用或值,取决于捕获模式),并且具有与lambda主体等效的`operator()`.然后实例化该类以创建lambda表达式的结果值. (3认同)