Search code examples
c++c++11packaged-task

Why is std::packaged_task<void()> not valid?


Using MSVC2012,

The following code will compile and run as expected

std::packaged_task< int() > task( []()->int{ std::cout << "hello world" << std::endl; return 0; } );
std::thread t( std::move(task) );
t.join();

while the following code will fail to compile and run

std::packaged_task< void() > task( [](){ std::cout << "hello world" << std::endl; } );
std::thread t( std::move(task) );
t.join();

Why is this so?

Edit: As a workaround, it is possible to use std::promise to get a std::future on a function that returns void

std::promise<void> promise;
auto future = promise.get_future();
std::thread thread( [](std::promise<void> &p){ std::cout << "hello world" << std::endl; p.set_value(); }, std::move(promise) );
future.wait();

Note that there is a bug in the vs2012 library with std::thread that forces you to pass the promise in as a l-value reference and move the promise in, it would not compile if you pass the promise by value or by r-value reference. This is supposedly because the implementation uses std::bind() which does not behave as expected.


Solution

  • This is a bug in MSVC2012. There are quite a few bugs in the thread library implementation that ships with MSVC2012. I posted a partial list in my blog post comparing it to my commercial Just::Thread library: http://www.justsoftwaresolutions.co.uk/news/just-thread-v1.8.0-released.html