gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-31 01:15:34 24 4
gpt4 key购买 nike

当我使用 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com