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.

1

There are 1 answers

0
273K On BEST ANSWER

std::packaged_task does not run a function/callable immediately, a function execution is deferred and parameters can be passed later to void operator()( ArgTypes... args );, therefore the possible constructor template< 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 constructor template< class Function, class... Args > explicit thread( Function&& f, Args&&... args );. You may consider it like sugar to avoid persistently writing code like std::thread(bind(f, 1)); instead of convenient std::thread(f, 1);.