move-semantics和std :: future

时间:2014-09-10 10:20:31

标签: c++ c++11 future move-semantics

我自己研究了C ++ 11的特性,并认识到了移动语义,并尝试将其应用于至少处理容器或“更大”对象的每个函数。现在我发现了一些我希望并行运行的任务,所以我会使用std :: future,但这些任务处理容器(在我的情况下返回一个容器)。 所以我有这个伪代码:

std::future<container&&> c = std::async([]()->container&&{ /* stuff return a local container object */ });

知道我问自己,容器rval ref的生命周期是如何控制的?如果我是对的并且在调用c.get()之前任务已完成,则将其存储。存储的值是否仍包含可用对象?

这是否能确保它的使用寿命?

std::future<container> c = std::async([]()->container&&{ /* same stuff -- ^ -- */ });
container cc = std::move(c.get());

1 个答案:

答案 0 :(得分:6)

看起来你的移动语义错误。

您应该按值返回,而不是通过右值引用返回,并让移动构造函数确保按值返回是有效的。否则,您可能会将悬挂引用返回到不再存在的对象。移动语义的要点是使价值便宜的传递对象,右值引用只是启用它的语言特征,目标不应该是为了它们而使用右值引用。

换句话说,您希望将来自lambda正文的数据移动到lambda的返回值,转移到未来的存储值。 移动数据。你不想传递一个没有移动任何内容的引用(你可以使用左值引用在C ++ 03中通过引用传递内容!)

您的lambda应按值返回,future应按值存储:

std::future<container> c = std::async([]()->container{ /* stuff */ });

并且您不需要使用std::move,唯一的期货会将存储的值作为右值返回,因此您可以自动从它移动而不使用std::move将其转换为右值:

container cc = c.get();   // cc will be move constructed