First, if you declare std::packaged_task to accept arguments, you must pass them to operator() , not the constructor. In one thread, you can:
std::packaged_task<int(int,int)> task(&ackermann); auto f=task.get_future(); task(3,11); std::cout<<f.get()<<std::endl;
To do the same with the thread, you must move the task to the stream and pass arguments too:
std::packaged_task<int(int,int)> task(&ackermann); auto f=task.get_future(); std::thread t(std::move(task),3,11); t.join(); std::cout<<f.get()<<std::endl;
Alternatively, you can link the arguments just before you build the task, in which case the task itself now has a signature that takes no arguments:
std::packaged_task<int()> task(std::bind(&ackermann,3,11)); auto f=task.get_future(); task(); std::cout<<f.get()<<std::endl;
Again you can do this and pass it to the stream:
std::packaged_task<int()> task(std::bind(&ackermann,3,11)); auto f=task.get_future(); std::thread t(std::move(task)); t.join(); std::cout<<f.get()<<std::endl;
All these examples should work (and do both with g ++ 4.6, and with MSVC2010 and just :: thread the implementation of the thread library). If this is not the case, then there is an error in the compiler or library. For example, the library shipped with g ++ 4.6 cannot process transferred objects only for moving, such as from std::packaged_task to std::thread (and thus cannot process the 2nd and 4th examples), since it uses std::bind as part of the implementation, and that the implementation of std::bind incorrectly requires the arguments to be copied.
Anthony williams
source share