Breaking the semantics of a copy, making it a movement, is a bad idea. If this was the only option, go for it, but it is not.
Instead, we can pass the moved value as an argument to lambda and move it to the packaging code.
curry_apply takes some value and a function object and returns this function object with the value associated with the first argument.
template<class T, class F> struct curry_apply_t { T t; F f; template<class...Args> auto operator()(Args&&...args) -> typename std::result_of_t<F&(T&, Args...)>::type { return f(t, std::forward<Args>(args)...); } }; template<class T, class F> curry_apply_t<typename std::decay<T>::type, typename std::decay<F>::type> curry_apply( T&& t, F&& f ) { return {std::forward<T>(t), std::forward<F>(f)}; }
Using:
template<class F> Packaged_Task(F&& f) { Promise<R> p; _future = p.get_future(); auto f_holder = curry_apply( std::move(_future), [](Future<R>& f) mutable { return std::move(f); }; );
basically we store the moved data outside of the lambda in a hand-written function object. Then we pass it as an lvalue argument at the beginning of the lambda argument list.
Here is a more complex version of the same solution.
source share