Hi,
Currently, when you construct a std::packaged_task from another one with
compatible signature, you get two independent shared states (ie. two
futures), because the wrapping task contains the wrapped task as if it
was any other callable.
The ship has sailed for implicit conversions, but as I myself have found
and these SO questions suggest:
https://stackoverflow.com/questions/31072279/implementing-a-simple-generic-thread-pool-in-c11
https://stackoverflow.com/questions/28179817/how-can-i-store-generic-packaged-tasks-in-a-container
There is a hole in the standard library, since while you can always
construct a std::function with a compatible signature in the first
place, this does not work for packaged_task, since the return type of
the signature determines the type of future returned from get_future().
What these SO users need, and I needed, too, recently, was a
std::packaged_task<void()> for type erasure constructed from a
packaged_task<R()>, on which get_future() was called. Alternatively,
they could use a unique_function, which, however, is also lacking in the
standard.
Now, instead of cluttering the API of packaged_task, I imagine that a
simple cast function could do the job:
fun: some callable compatible with R()
m_tasks: a container of packaged_task<void()>
auto task = std::packaged_task<R()>{fun};
auto result = task.get_future();
m_tasks.push_back(packaged_task_cast<void()>(std::move(task)));
I deliberately didn't look into how to implement this, yet, as I wanted
to retain the API user's view for now.
Alternatively, the future and the packaged_task objects could be created
together, with a make_ function. This could also supply the much-missed
feature of binding arguments to the invocation, much like
make_shared/unique allow to pass arguments to the ctor while the
shared_ptr/unique_ptr ctors only take pointers:
auto r = std::make_packaged_task_and_future<void()>(fun, args...);
m_tasks.push_back(std::move(r.task)); // a packaged_task<void()>,
since this is what we asked for
return std::move(r.future); // a future<R>, deduced from the return
type of 'fun'
Opinions?
Thanks,
Marc