c++ - 为什么在使用 boost::copy_exception 时会丢失类型信息?

标签 c++ exception boost

当我使用 boost::copy_exception 将异常复制到 exception_ptr 时,我丢失了类型信息。看看下面的代码:

try {
    throw std::runtime_error("something");
} catch (exception& e) {
    ptr = boost::copy_exception(e);
}
if (ptr) {
    try {
        boost::rethrow_exception(ptr);
    } catch (std::exception& e) {
        cout << e.what() << endl;
        cout << boost::diagnostic_information(e) << endl;
    }
}

由此,我得到以下输出:

N5boost16exception_detail10clone_implISt9exceptionEE
Dynamic exception type: boost::exception_detail::clone_impl<std::exception>
std::exception::what: N5boost16exception_detail10clone_implISt9exceptionEE

所以基本上 boost::copy_exception 静态复制了它得到的参数。

如果我用 boost::enable_current_exception 抛出异常,这个问题就解决了,就像这样。

try {
    throw boost::enable_current_exception(std::runtime_error("something"));
} catch (...) {
    ptr = boost::current_exception();
}
if (ptr) {
    try {
        boost::rethrow_exception(ptr);
    } catch (std::exception& e) {
        cout << e.what() << endl;
        cout << boost::diagnostic_information(e) << endl;
    }
}

问题是有时异常是由不使用 boost::enable_current_exception 的库抛出的。在这种情况下,除了一个一个地捕获每一种可能的异常并在每个异常上使用 boost::copy_exception 之外,还有什么方法可以将异常放入 exception_ptr 中吗?

最佳答案

这是设计使然,您的分析是正确的:使用的是静态类型,而不是动态类型。事实上,为了避免这种意外,boost::copy_exception 在导致 C++11 的过程中变成了 std::make_exception_ptr。这样一来,current_exception(无论是 Boost 版本还是 C++11 版本)是用于正确捕获当前异常的正确方法就更清楚了。在您的代码中使用启用 Boost.Exception 的异常时,我强烈建议您使用 BOOST_THROW_EXCEPTION,或者至少使用 boost::throw_exception

当谈到第三方代码时,除了您已经提到的那个,或者其他一些道德等同的解决方案(比如 dynamic_cast-ing 到构成异常类型层次结构或层次结构,或 typeid 滥用)。

在这方面,异常处理与处理一个或多个多态类型层次结构相同,并且您在这种情况下尝试的操作是虚拟拷贝,也称为克隆:您的代码被侵入式设计以支持那(就像使用例如 BOOST_THROW_EXCEPTION(e); 而不是 throw e; 时的情况),否则你将痛苦地遍历继承树。请注意,您至少可以将这种痛苦重构到一个站点中,这样您最终会得到例如

try {
    third_party_api();
} catch(...) {
    ptr = catch_exceptions_from_api();
}

关于c++ - 为什么在使用 boost::copy_exception 时会丢失类型信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9973499/

相关文章:

C++:将 "boost::multiprecision::float128"转换为 "double"

c++ - c表达式和c++表达式的区别

c++ - 返回 vector 对象的引用,好主意吗?

c++ - BOOST_SCOPE_EXIT 在幕后做了什么?

c# - 对象引用的自定义消息未设置为对象的实例

C++ 异常处理中的 Else 语句

c++ - 按字母降序排列列表并打印列表

java - 丢失线程时出现异常

python - asio 无法将消息写入服务器两次以上

c++ - 如何在文件中保存 vector<vector<vector<float>>> 并检索数据?