为什么在使用boost::copy_exception时会丢失类型信息
Why do I lose type information when using boost::copy_exception?
当我使用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
中吗?
这是经过设计的,您的分析是正确的:使用的是静态类型,而不是动态类型。事实上,为了避免这种意外,在导致C++11的过程中,boost::copy_exception
变成了std::make_exception_ptr
。这样,current_exception
(无论是Boost版本还是C++11版本)都是正确的,可以用来正确捕获当前异常。当谈到在代码中使用Boost.Exception-enabled异常时,我强烈建议使用BOOST_THROW_EXCEPTION
,或者至少使用boost::throw_exception
。
当涉及到第三方代码时,除了您已经提到的解决方案,或者其他一些道德等价的解决方案(例如dynamic_cast
,用于组成一个或多个异常类型层次结构的不同叶类,或者typeid
滥用)之外,没有其他解决方案。
在这方面,异常处理与处理一个或多个多态类型层次结构相同,在这种情况下,您尝试的操作是一个虚拟副本,也称为克隆:要么您的代码被侵入性地设计为支持它(例如使用BOOST_THROW_EXCEPTION(e);
而不是throw e;
时的情况),要么您将痛苦地遍历继承树。请注意,您至少可以将这种痛苦重构为一个站点,这样您最终会得到例如
try {
third_party_api();
} catch(...) {
ptr = catch_exceptions_from_api();
}
- Keil armcc 生成类型信息名称,即使使用 --no_rtti_data
- 使用 trie 数据结构链接不同类型的信息
- 错误:未定义对"静脉类型信息::电池访问"的引用
- 只知道运行时的数据类型.如何将数据详细信息隐藏到使用它们的其他类
- 自动初始值设定项类型ID 信息
- 元数据操作失败LNK2022错误 (8013118D):重复类型中的布局信息不一致 (选择设备参数):(0x020002
- 针对特殊情况,使用其他状态信息扩展基元类型
- 如何从模板获取类型和值信息
- 将不同的模板化类存储在一个容器中,而不会丢失有关其类型的信息
- 如何在编译过程中输出C 类型信息
- 如何在C 中检查确切的类型信息(具有CV-REF-POIRT特征)
- 为什么类型转换对象不会更改其地址?有关对象类型的信息存储在哪里?
- 共享库中非模板基的模板子类导致未定义的符号类型信息'class'链接错误
- 为什么C++不使用集中存储类型信息以实现高效的 RTTI
- 仅使用有关类型而不是对象的信息返回调用的类型
- 给定DDS主题名称,可以在运行时确定主题类型信息
- 使用友元函数从多态类中检索类型信息
- 如何在函数模板中隐式推导数组中元素的类型信息
- 使用标准类型的动态类型信息实例化标识符
- 如何在 c++ 中获取有关服务的启动类型的信息