使用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