user3186766
user3186766

Reputation: 71

How to move an object to a std::async()?

I need move an object to a async-function to let the other function manage my resources. But it seems very difficult. For example, I want to send a fstream to an async-function.

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

I want to:

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

It can't be compiled.

But

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

can be compiled.

How could I do that?

Upvotes: 5

Views: 1315

Answers (1)

Xarn
Xarn

Reputation: 3551

That is the proper way to do it. (There is literally nothing to add to the answer)

If you are testing it with something like Coliru, note that you won't see any output from, say

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

because without specifying launch policy (std::launch::async or std::launch::deferred), std::launch::deferred is used and thus the async call is lazy evaluated. (It waits with evaluation until first call to nontimed wait on the returned future.)


This assumes that you want a future, not a real thread. If you want real thread, std::thread is what you want.

---edit---
After a bit of searching I found out that libstdc++ hasn't implemented swap and move for file streams (search for 27.9). So, if you are using GCC or Clang with libstdc++, the answer is that you cannot do what you are asking for, even though it is fully compliant with standard.

Also it seems that Visual Studio has a completely different bug, that however also prevents this use case. For more details and possible workaround refer to this SO question and answer. Basically, while it has implemented move constructors, std::async constructor copies instead of decays the arguments.

Upvotes: 5

Related Questions