使用MSVC2012,为什么std :: packaged_task <void()>无效?
将下面的代码编译和运行如预期
std::packaged_task< int() > task([]()->int{ std::cout << "hello world" << std::endl; return 0; });
std::thread t(std::move(task));
t.join();
,而下面的代码将无法编译和运行
std::packaged_task< void() > task([](){ std::cout << "hello world" << std::endl; });
std::thread t(std::move(task));
t.join();
为什么会这样呢?
编辑: 作为一种变通方法,可以使用std ::承诺得到一个std ::将来返回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();
注意,有在vs2012库中的缺陷的功能使用std :: thread强制你将这个承诺作为一个l值引用传递,并将promise传递给它,如果你通过值或r值引用传递promise,它将不会编译。据推测,这是因为实现使用了std :: bind(),它的行为并不像预期的那样。
有趣......第二个编译时出现什么错误? – Yuushi
这可能是MSVC++中的一个错误。 –
从我追溯到它们的实现,它最终归结为它们的函数对象执行状态的存储,特别是在名为'_State_manager'的模板类中。 '_State_manager'没有专门针对'void'状态,这就像一个bug。我也可以完全出去吃午饭,但那似乎一切都崩溃了。 –
WhozCraig