Я пытаюсь использовать исключения буста и падаю.
Есть код проблемы:
struct exception_base : virtual std::exception, virtual boost::exception
{
exception_base(std::exception&& e)
: std::exception(e)
{}
};
int main()
{
std::string exception_description;
try
{
BOOST_THROW_EXCEPTION(exception_base(std::runtime_error("hello exception")));
}
catch (exception_base& ex)
{
exception_description = boost::diagnostic_information(ex);
}
return 0;
}
В этом случае значение исключения_данных имеет последняя строка — «std :: exception :: what: неизвестное исключениеMsgstr «Это неожиданное значение. Если я изменю BOOST_THROW_EXCEPTION на обычный бросок — последняя строка значения exception_description выглядит ожидаемой -«std :: exception :: what: привет исключение«
Так как правильно использовать BOOST_THROW_EXCEPTION?
Ваш пользовательский класс исключений не является необходимым и является основной причиной ваших проблем. Если вы удалите его, вы можете просто сделать это:
BOOST_THROW_EXCEPTION(std::runtime_error("hello exception"));
Затем:
catch (const std::exception& ex)
И код будет работать так, как вы ожидаете.
Почему это не работает раньше? Ну твой exception_base
класс не имеет хранилища для сообщения об ошибке, поэтому, когда вы создаете его из std::exception
он не может сохранить сообщение (например, из оригинала runtime_error
).
Вы можете исправить это различными способами, но в конечном итоге они сводятся к одному и тому же: если вы хотите, чтобы ваш пользовательский класс исключений содержал строку сообщения, он должен каким-то образом содержать эту строку сообщения.
Я поклонник не определения пользовательских типов исключений в 95% случаев, поэтому я бы посоветовал вам просто сделать это простым и использовать runtime_error
(И / или logic_error
).
Обратите внимание, что BOOST_THROW_EXCEPTION
автоматически добавляет boost::exception
как базовый класс для брошенного типа, так что вам все равно не нужно делать это самостоятельно — в этом нет никакого преимущества.
Других решений пока нет …