Hm, it seems to be a bug in VC11. Apparently the implementation of async
doesn't really forward the arguments but copies them.
From the top of my head I would create a small wrapper for the rvalue that move-constructs the element when the wrapper is copied:
template <typename T>
struct rvref_wrapper {
rvref_wrapper(T&& value) : value_(std::move(value)) {}
rvref_wrapper(rvref_wrapper const& other) : value_ (other.get()) {}
T&& get() const { return std::move(value_); }
mutable T value_;
};
template <typename T>
auto rvref(T&& x) -> rvref_wrapper<typename decay<T>::type> {
return std::move(x);
}
Then you'd have to modify your test scenario, so that the lambda in Test2
takes the wrapper instead of the future
itself:
template <typename T, typename Work>
void Test2(future<T> f, Work w)
{
async([](rvref_wrapper<future<T>> fr, Work w) {
// acquire future<T>&& here
future<T> f(fr.get());
// e.g. call work with future value
w(f.get());
}, rvref(f), move(w));
}
int main()
{
future<int> x = std::async([]()->int{
std::this_thread::sleep_for(std::chrono::microseconds(200));
return 10;
});
Test2(std::move(x), [](int x){});
return 0;
}
Looks a little bit ugly, but at least it compiles. Hope that helps you!