如何将对象移动到std :: async()?

时间:2014-02-09 10:00:41

标签: c++ c++11

我需要将对象移动到异步函数以让其他函数管理我的资源。但这似乎很难。 例如,我想将一个fstream发送到async-function。

void asv(std::ofstream s)
{
//do something.
}

我想:

std::ofstream s("afs");
std::async(asv,std::move(s));

无法编译。

但是

std::ofstream s("afs");
asv(std::move(s));

可以编译。

我怎么能这样做?

1 个答案:

答案 0 :(得分:5)

这是正确的方法。 (答案中几乎没有任何内容可以添加)

如果您使用像Coliru这样的东西进行测试,请注意您不会看到任何输出,比如说

void asv(std::string s){
    std::cout << s << std::endl;
}

因为未指定启动策略(std::launch::asyncstd::launch::deferred),所以使用了std::launch::deferred,因此异步调用是惰性求值的。 (它等待评估,直到第一次呼叫非定时等待返回的未来。)


这假设你想要一个未来,而不是一个真正的线程。如果你想要真正的线程,std::thread就是你想要的。

--- ---编辑
经过一些搜索后,我发现了libstdc ++ hasn't implemented swap and move for file streams(搜索27.9)。因此,如果您使用GCC或Clang与libstdc ++,答案是您无法满足要求,即使它完全符合标准。

似乎Visual Studio有一个完全不同的bug,但是这也会阻止这个用例。有关更多详细信息和可能的解决方法,请参阅this SO question and answer. 基本上,虽然它已实现了移动构造函数,但std::async构造函数副本而不是衰减参数。