Это минимальный пример кода, как исключение перемещается с использованием std :: exception_ptr:
#include <iostream>
#include <boost/thread.hpp>
#include <boost/optional.hpp>
#include <boost/variant.hpp>
int main() {
try
{
throw std::runtime_error("Error!");
}
catch (...)
{
boost::optional<boost::variant<int, std::exception_ptr>> v(std::move(std::current_exception()));
boost::promise<int> p;
boost::future<int> f = p.get_future();
try
{
std::rethrow_exception(std::move(boost::get<std::exception_ptr>(std::move(v.get()))));
}
catch (...)
{
p.set_exception(std::move(std::current_exception()));
}
try
{
f.get();
}
catch (const std::exception &e)
{
// This is what I would like to see:
std::cerr << "Error: " << e.what() << std::endl;
}
catch (...)
{
// This is what I get instead:
std::cerr << "Unknown error" << std::endl;
}
}
return 0;
}
Я хотел бы сохранить фактический объект std :: runtime_error и получить его в последнем выражении f.get (). Вместо этого я получаю неизвестное исключение, которое не является производным от std :: exception.
Когда я удаляю последний оператор catch (...), я получаю следующий вывод:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<std::__exception_ptr::exception_ptr>'
Я бы хотел избежать любых операций клонирования / копирования. Я хочу сохранить свой экземпляр std :: runtime_error и переместить его до конца (последний вызов f.get ()).
Если есть лучший способ сохранить какое-либо исключение, чем std :: exception_ptr, пожалуйста, сообщите мне, и я буду использовать его вместо этого. Folly использует шаблон класса folly :: exception_wrapper, но я не знаю других стандартных типов.
Вы можете посмотреть файлы оригинального проекта здесь: https://github.com/tdauth/cpp-futures-promises/tree/master/src/advanced
Различные повторные выбросы требуются, потому что я использую тип оболочки Try и метод Promise :: tryComplete.