试图传递由
boost::bind
到
create_thread
因为我在我的
answer
回答你之前的问题。
使用lambda的尝试应该可以编译,但它有一个微妙的错误,会导致未定义的行为。我之前的回答可能误导了你,但这就是发布
MCVE
非常重要。您在上一个问题中发布的小片段并没有显示您打算如何使用代码。
lambda的问题是它只存储对
unique_ptr
。在呼叫之前,您不会转移所有权
RunSimulation
执行,换句话说,所有权的转移只在线程执行开始后发生。但到那时
for
内循环
main
可能已经转移到下一个迭代,导致
Result
由
唯一(&P)
在要删除的上一迭代中。取消引用
唯一(&P)
在内部
运行模拟
然后导致未定义的行为。
解决方法是转让
唯一(&P)
立即转移到lambda,然后让lambda再次将调用中的所有权转移到
运行模拟
。下面的lambda表达式可以执行您想要的操作
[&sim, r=std::move(r)] () mutable {
sim->RunSimulation(std::move(r));
}
为了解释发生了什么,lambda正在捕捉
sim
通过引用(
&sim
)它使用C++14的lambda init捕获来转移
r
在内部
主要的
到
r
那是lambda的成员(
r=std::move(r)
)(你可以打电话给lambda的成员
r
如果你想的话,可以做点别的)。lambda本身需要
mutable
因为你需要-
const
访问
r
数据成员,以便您可以
move
打电话时
运行模拟
.
不幸的是,你的问题还没有结束。使命感
创建线程
使用上面的lambda仍然无法编译,因为根据
documentation
,它要求可调用对象是可复制的。你的lambda不可复制,因为它有一个
唯一(&P)
数据成员。
解决方法是创建
boost::thread
然后
add_thread
它到
thread_group
.
auto t = new boost::thread([&sim, r=std::move(r)] () mutable {
sim->RunSimulation(std::move(r));
});
threads.add_thread(t);
请注意,我找不到任何关于异常安全保证的文档
添加线程
品牌。因此,如果在
添加线程
尝试将新线程添加到
线程组
你的
thread
对象可能泄漏。
Live demo
最后,我认为你需要重新思考你的设计。据推测
后果
对象应该保存模拟结果。有什么意义
运行模拟
将其存储在
后果
如果您无法访问
后果
在内部
主要的
模拟结束后?
正如我在上一个答案的评论中所建议的,您可能应该创建一个容器
后果
中的
主要的
并将对这些容器的元素的引用传递给
运行模拟
.