You can use shared_future . This is the easiest.
However, this does not help you move. If you really need to move, we can do this with the move_helper function and the class:
template<class T, class F=void> struct move_helper_t { T t; F f; template<class...Args> auto operator()(Args&&...args) ->typename std::result_of< F&(T&, Args...) >::type { return f(t, std::forward<Args>(args)...); }
In MSVC 2013, you may need to declare a constructor in move_helper_t . I donβt remember how well their return {} code is written.
f = p.get_future(); task = move_helper(std::move(f)) ->* [](std::future<int>& f){
->* binds move_helper to lambda. It then returns the called object, which will be passed to std::future<int>& as the first argument when called.
Due to the way it is written, you can even bind it:
auto f = p.get_future(); auto f2 = p2.get_future(); task = move_helper(std::move(f)) ->* move_helper(std::move(f2)) ->* [](std::future<int>& f, std::future<char>& f2){
to move more than one argument to lambda.
In both cases, task can be called by task() - the operation ->* binds the lambda up and passes the futures on call.
Living example .
Please note that this solves the problem of translating the future into lambda. If you want to store the lambda in std::function , this will not help you, since functions must be copied.
template<class F> struct shared_function { std::shared_ptr<F> pf; template<class ...Args> typename std::result_of<F&(Args...)>::type operator()(Args&&...args) const { return (*pf)(std::forward<Args>(args)...); } }; template<class F, class dF=typename std::decay<F>::type > shared_function< dF > make_shared_function( F&& f ) { return {std::make_shared<dF>(std::forward<F>(f))}; }
this takes a movable lambda and wraps it in a generic pointer and provides operator() for you. But first, using future move it to the lambda using the above technique, and then wrap this lambda in a common function to pass it to std::function , itβs funny: just use shared_future first.
On the side, in theory, a packaged_task only requires moving, but I'm not sure that MSVC2013 supports this requirement.