move-semantics和std :: future

Jos*_*ens 4 c++ future move-semantics c++11

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

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

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

这确保了它的寿命吗?

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

Jon*_*ely 6

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

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

换句话说,您希望数据从lambda主体移动到lambda的返回值,转换为将来的存储值.这会移动数据.你不想传递一个不会移动任何东西的引用(你可以使用左值引用在C++ 03中通过引用传递东西!)

你的lambda应该按值返回,并且future应该按值存储:

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

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

container cc = c.get();   // cc will be move constructed
Run Code Online (Sandbox Code Playgroud)