I'm trying to create a promise from a template function which accepts a Callable type. But I'm not sure how to do it. I tried using std::invoke_result_t
, but that needs the arguments to know the result type, something which I won't know when I construct the promise.
Any way in which I can deduce the return type? I guess it may be impossible in the case of a generic lambda, but does anything work on non generic lambda cases?
template <typename Callable, typename Promise>
class Job {
public:
Job(Callable&& c, Promise&& p)
: callable(std::move(c))
, promise(std::move(p))
{}
auto getFuture() {
return /* a std::shared_future */;
}
template<typename... Args>
void call(Args&&... args) {
promise.set_value(std::invoke(callable, args...));
}
private:
Callable callable;
Promise promise;
};
template<typename Callable>
decltype(auto) makeJob(Callable&& c) {
std::promise</* some type */> promise = /* something */;
return Job(std::forward<Callable>(c), std::move(promise));
}
int main() {
f1 = [](int arg){return arg;};
auto job = makeJob(std::move(f1));
auto future = job.getFuture();
job.call(1);
std::cout << future.get() << '\n';
}
You tagged C++17 so...
std::function
and deduction guides are your friends.You can detect the return type of the callable with something as
so your
makeJob()
function can be writtenThe same in the
Job
class.Obviously this works because
f1
has a return type that doesn't depend from the arguments; with a generic lambda
this solution doesn't works anymore and I don't think that you can write something to get the return type without knowing the argument type.
The following is a full compiling example