Here is a simple code snippet:
#include <thread>
#include <future>
#include <functional>
void foo(int){}
int main()
{
std::thread(foo, 1).join(); //works indeed
std::packaged_task<void(int)> task{foo, 1}; //complian
std::packaged_task<void(int)> task{std::bind(foo, 1)};
}
Both std::thread()
and std::packaged_task()
accept callable targets, why the code for std::packaged_task()
is a little different? Why does not make the std::packged_task()
works like std::thread()
(i.e. accepts arguments like std::thread
)?
The class template std::packaged_task wraps any Callable target (function, lambda expression, bind expression, or another function object) so that it can be invoked asynchronously. Its return value or exception thrown is stored in a shared state which can be accessed through std::future objects.
std::packaged_task
does not run a function/callable immediately, a function execution is deferred and parameters can be passed later tovoid operator()( ArgTypes... args );
, therefore the possible constructortemplate< class Function, class... Args > explicit packaged_task( Function&& f, Args&&... args );
is not necessary.However
std::thread
runs a function/callable immediately, thus parameters must be passed to the constructortemplate< class Function, class... Args > explicit thread( Function&& f, Args&&... args );
. You may consider it like sugar to avoid persistently writing code likestd::thread(bind(f, 1));
instead of convenientstd::thread(f, 1);
.