Lambdas

时间:2015-11-17 23:09:33

标签: c++ c++11 lambda boost

将lambda表达式传递给函数时,是否可以将lambda / closure存储在某处以供以后使用,即使该函数返回后也是如此?

据我所知,lambda生成一个临时未命名的函数对象,该函数在函数返回后被销毁。

#include <boost/signals2.hpp>

boost::signals2::signal<void()> sig;

void foo()
{
    sig.connect([]{ /* do something */ });
}

int main()
{
    foo();

    sig();

    return 0;
}

1 个答案:

答案 0 :(得分:5)

Lambda闭包不是魔术。它们就像任何其他对象一样工作。您可以按引用或按值传递它们,制作副本并存储它们以供以后使用。只要你不玩肮脏的技巧,他们就会按预期行事。

在关闭时通过引用捕获的对象的生命周期变得更加棘手。 Lambdas不会神奇地将C ++变成托管语言。一旦对象的范围结束,它们将被销毁,并且闭包可能保留的任何引用将悬挂,等待稍后爆炸。如果你希望保持lambda闭包的持续时间超过包含捕获对象的范围,那么你最好不要捕获按值。在极少数情况下,您可能希望使用std::shared_ptr s(您按照值进行捕获)。

最后要注意的是,非捕获lambda可以隐式转换为函数指针。一旦发生这种转换,闭包对象就可能被破坏,函数指针的行为就像任何其他函数指针一样。

如果您对lambda表达式感到困惑,我建议您在想象中或代码的丢弃副本中替换它们 - 使用手动编写的struct实例,其中包含每个捕获的数据成员对象和重载operator()。然后,您应该能够更舒适地推断代码。