Это сделано специально, и ваш анализ верен: используется статический тип, а не динамический тип. Фактически, чтобы избежать этого сюрприза, boost::copy_exception
стал std::make_exception_ptr
во время процесса, который привел к C ++ 11. Таким образом, становится понятнее, что current_exception
(будь то версия Boost или версия C ++ 11) - это то, что нужно для правильной записи текущего исключения. Я настоятельно рекомендую использовать BOOST_THROW_EXCEPTION
или, по крайней мере, boost::throw_exception
, когда дело доходит до использования исключений с поддержкой Boost.Exception в вашем коде.
Когда речь идет о стороннем коде, не существует другого решения, кроме того, которое вы уже упомянули, или какого-либо другого морального эквивалента (например, dynamic_cast
) для различных конечных классов, составляющих иерархию типов исключений или иерархии. или typeid
злоупотребление).
В этом отношении обработка исключений аналогична работе с одной или несколькими иерархиями полиморфных типов, и операция, которую вы пытаетесь в этом случае, представляет собой виртуальную копию, также известную как клонирование: либо ваш код навязчиво предназначен для поддержки это (как в случае использования, например, BOOST_THROW_EXCEPTION(e);
вместо throw e;
), или вы будете мучительно обходить дерево наследования. Обратите внимание, что вы можете, по крайней мере, рефакторировать эту боль только на одном сайте, так что в итоге вы получите, например,
try {
third_party_api();
} catch(...) {
ptr = catch_exceptions_from_api();
}