重要更新:当我提出这个问题时,显然我得出了错误的结论。感谢我发现的响应,lambda函数[=]()
在多线程场景中运行良好。我为提出这个令人困惑的问题而道歉。请投票结束,因为这不是问题。
在我们公司,我们编写了一个库函数,在一个单独的线程中异步调用一个函数。它使用继承和模板魔法的组合工作。客户端代码如下所示:
DemoThread thread;
std::string stringToPassByValue = "The string to pass by value";
AsyncCall(thread, &DemoThread::SomeFunction, stringToPassByValue);
自从引入lambda函数以来,我想将它与lambda函数结合使用。我想写下面的客户端代码:
DemoThread thread;
std::string stringToPassByValue = "The string to pass by value";
AsyncCall(thread, [=]()
{
const std::string someCopy = stringToPassByValue;
});
更新:与我在提出此问题时首先相信的情况相反,此代码运行正常。
<击>
现在,使用Visual C ++ 2010,此代码不起作用。会发生什么是stringToPassByValue
未被复制。而是“按值捕获”功能通过引用传递数据。结果是,如果函数在stringToPassByValue
超出范围后执行,则应用程序崩溃,因为它的析构函数已经被调用。
所以我想知道:是否可以将数据作为副本传递给lambda函数?
注意:一种可能的解决方案是修改我们的框架以传递lambda参数声明列表中的数据,如下所示:
DemoThread thread;
std::string stringToPassByValue = "The string to pass by value";
AsyncCall(thread, [=](const std::string stringPassedByValue)
{
const std::string someCopy = stringPassedByValue;
}
, stringToPassByValue);
然而,这个解决方案非常冗长,我们的原始函数指针解决方案既简短又易于阅读。
击><击> 撞击>
更新:AsyncCall
的完整实施太大了,无法在此处发布。简而言之,发生的是AsyncCall
模板函数实例化一个包含lambda函数的模板类。此类派生自包含虚拟Execute()
函数的基类,并且在AsyncCall()
调用时,函数调用类被置于调用队列中。然后,另一个线程通过调用虚拟Execute()
函数来执行排队调用,该函数以多态方式分派给模板类,然后模板类执行lambda函数。