Исключения из boost::async() теряют тип
Буст-версия: 1.61, GCC версия 6.2.0, C++14
Исключения внутри boost::async()
вызов, кажется, теряет свой тип, в то время как он работает правильно с std::async
, Есть ли принципиальная разница между std::async
а также boost::async
Я скучаю?
Следующий код работает (используя std::async
):
#include <iostream>
#include <stdexcept>
#include <future>
using namespace std;
struct MyException : std::exception {
const char* what() const noexcept override { return "message"; }
};
int main() {
try {
auto future = std::async(std::launch::async, [] { throw MyException(); });
future.get();
} catch (const MyException& e) {
cout << "MyException caught. Message: " << e.what() << endl;
} catch (const std::exception& e) {
cout << "std::exception caught. Message: " << e.what() << endl;
}
}
и выводы
$ g++ test.cpp -std=c++14 -lpthread -lboost_thread -lboost_system && ./a.out
MyException caught. Message: message
Тем не менее, следующий код (это то же самое, просто используя boost::async
вместо std::async
) не работает должным образом:
#include <iostream>
#include <stdexcept>
#include <boost/thread/future.hpp>
using namespace std;
struct MyException : std::exception {
const char* what() const noexcept override { return "message"; }
};
int main() {
try {
auto future = boost::async(boost::launch::async, [] { throw MyException(); });
future.get();
} catch (const MyException& e) {
cout << "MyException caught. Message: " << e.what() << endl;
} catch (const std::exception& e) {
cout << "std::exception caught. Message: " << e.what() << endl;
}
}
Это выводит:
$ g++ test.cpp -std=c++14 -lpthread -lboost_thread -lboost_system && ./a.out
std::exception caught. Message: std::exception
Это также не работает для boost::future::then
продолжения:
#include <iostream>
#include <stdexcept>
#define BOOST_THREAD_VERSION 4
#include <boost/thread/future.hpp>
using namespace std;
struct MyException : std::exception {
const char* what() const noexcept override { return "message"; }
};
int main() {
try {
auto future = boost::make_ready_future(3).then([](boost::future<int>) -> int { throw MyException(); });
future.get();
} catch (const MyException& e) {
cout << "MyException caught. Message: " << e.what() << endl;
} catch (const std::exception& e) {
cout << "std::exception caught. Message: " << e.what() << endl;
}
}
выходы:
$ g++ test.cpp -std=c++14 -lpthread -lboost_thread -lboost_system && ./a.out
std::exception caught. Message: std::exception
Таким образом, конкретный тип исключения, похоже, теряется при пересечении границы потока. Тем не менее, похоже, что это не связано с многопоточностью, потому что согласно моим тестам, то же самое верно для std::launch::deferred
(который отлично работает) и boost::launch::deferred
(который теряет тип исключения).