Исключения из 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 (который теряет тип исключения).

0 ответов

Другие вопросы по тегам