The code below is based on Herb Sutter's ideas of an implementation of a .then() type continuation.
template<typename Fut, typename Work>
auto then(Fut f, Work w)->std::future<decltype(w(f.get()))>
{ return std::async([=] { w(f.get()); }); }
This would be used like auto next = then(f, [](int r) { go_and_use(r); });
or similar.
This is a neat idea, but as it stands will not work (futures are move only and not copyable). I do like the idea as it is likely to appear in upcoming versions of c++ as far as I can guess (although as .then() or even await.)
Before making the futures shared or similar I wonder what the stack overflow community would think of this implementation specifically with improvements and suggestions (even shared futures)?
Thanks in advance for any suggestions.
(I am aware this is a fix till a standards based mechanism exists as it will cost a thread (maybe))).
I find 3 problems with the above implemention:
std::shared_future
as Fut
.std::launch::async
it might be deferred, thus the continuation is not invoked as one would expect.I've tried to address these:
template<typename F, typename W, typename R>
struct helper
{
F f;
W w;
helper(F f, W w)
: f(std::move(f))
, w(std::move(w))
{
}
helper(const helper& other)
: f(other.f)
, w(other.w)
{
}
helper(helper&& other)
: f(std::move(other.f))
, w(std::move(other.w))
{
}
helper& operator=(helper other)
{
f = std::move(other.f);
w = std::move(other.w);
return *this;
}
R operator()()
{
f.wait();
return w(std::move(f));
}
};
}
template<typename F, typename W>
auto then(F f, W w) -> std::future<decltype(w(F))>
{
return std::async(std::launch::async, detail::helper<F, W, decltype(w(f))>(std::move(f), std::move(w)));
}
Used like this:
std::future<int> f = foo();
auto f2 = then(std::move(f), [](std::future<int> f)
{
return f.get() * 2;
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With