C++ Lambdas的参考参数

C++ Lambdas的参考参数,c++,c++11,lambda,boost,C++,C++11,Lambda,Boost,将lambda表达式传递给函数时,我是否可以将lambda/闭包存储在某个位置,以便在该函数返回后使用 据我所知,lambda生成一个临时的未命名函数对象,该对象在函数返回后被销毁 #include <boost/signals2.hpp> boost::signals2::signal<void()> sig; void foo() { sig.connect([]{ /* do something */ }); } int main() { fo

将lambda表达式传递给函数时,我是否可以将lambda/闭包存储在某个位置,以便在该函数返回后使用

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

#include <boost/signals2.hpp>

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

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

int main()
{
    foo();

    sig();

    return 0;
}
#包括
boost::signals2::sig信号;
void foo()
{
sig.connect([]{/*做点什么*/});
}
int main()
{
foo();
sig();
返回0;
}

Lambda闭包不是魔法。它们的工作原理与任何其他物体一样。您可以通过引用或值传递它们,复制并存储它们以供以后使用。只要你不耍下流的把戏,他们就会表现得像你预料的那样

当涉及到闭包中引用捕获的对象的生命周期时,它变得更加棘手。LAMBDAS不神奇地将C++变成一种管理语言。一旦对象的作用域结束,它们将被销毁,闭包可能保留的任何引用都将悬空,等待稍后爆炸。如果您希望保持lambda闭包的时间超过包含捕获对象的作用域的持续时间,那么最好按值捕获。在极少数情况下,您可能希望使用
std::shared_ptr
s(通过值捕获)

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


如果您对lambda表达式感到困惑,我建议您将它们替换为手动编写的
结构的实例化,该结构具有每个捕获对象的数据成员和重载的
操作符()
。然后,您应该能够更轻松地对代码进行推理。

Lambda闭包不是魔术。它们的工作原理与任何其他物体一样。您可以通过引用或值传递它们,复制并存储它们以供以后使用。只要你不耍下流的把戏,他们就会表现得像你预料的那样

当涉及到闭包中引用捕获的对象的生命周期时,它变得更加棘手。LAMBDAS不神奇地将C++变成一种管理语言。一旦对象的作用域结束,它们将被销毁,闭包可能保留的任何引用都将悬空,等待稍后爆炸。如果您希望保持lambda闭包的时间超过包含捕获对象的作用域的持续时间,那么最好按值捕获。在极少数情况下,您可能希望使用
std::shared_ptr
s(通过值捕获)

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


如果您对lambda表达式感到困惑,我建议您将它们替换为手动编写的
结构的实例化,该结构具有每个捕获对象的数据成员和重载的
操作符()
。然后,您应该能够更轻松地对代码进行推理。

一个代码示例和对您尝试执行的操作的描述将在这里起到很大作用。否则,答案是“是”或“否”。C++不允许“裸方法”,不要求您定义类吗?YUP我添加了一些代码。谢谢你的建议。什么是
sig()调用您的示例?这是假设的代码,还是实际有效的代码?请尝试阅读代码,它没有那么长。:)是的。当然,我不是C++大师,但不应该把代码< >()(代码)附加到某个对象上,或者至少是一些方法声明?代码示例和你要做的描述将在这里很长的路要走。否则,答案是“是”或“否”。C++不允许“裸方法”,不要求您定义类吗?YUP我添加了一些代码。谢谢你的建议。什么是
sig()调用您的示例?这是假设的代码,还是实际有效的代码?请尝试阅读代码,它没有那么长。:)是的。当然,我不是C++大师,但不应该将某个对象附加到某个对象上,或者至少是某种方法声明?无效函数()?int a;线程MyType([A] {/**做*/});} Joseph No,原因有:(1)因为你既没有<代码>(),也没有代码>也没有>代码>
std::thread
,其析构函数将在作用域退出时调用
std::terminate
。(2) 假设您调用
detach()
,则对
a
的引用将悬空。使用
join()
而不是
detach()
,就可以了,因为在函数完成之前,您会一直保持作用域的活动状态。我假设lambda实际上使用了
a
。一般来说,请尝试询问完整的、自包含的示例。很难解释不完整代码段的有效性。我的问题来自于看到许多示例,这些示例将lambda(带/out捕获)传递给一个作用域中的线程和信号对象,然后从另一个作用域启动线程/信号。有趣的是,这些对象(线程/信号)引用的是函数/对象,而不是副本。示例的来源是可靠的,这让我想知道lambdas闭包是否得到了不同的处理,生成的函子永远不会被销毁。正如我所说,我需要一个完整的示例来解释.void func(){int a;thread myThread([&a]{/*do something*/});}@Joseph No,原因如下:(1)由于您既不
join()
也不
detach()
线程
std::thread
,其析构函数将在作用域退出时调用
std::terminate
。(2) 假设您调用
detach()
,则对
a
的引用将悬空。使用<代码