为什么我失去类型信息使用boost :: copy_exception什么时候? [英] Why do I lose type information when using boost::copy_exception?
问题描述
当我使用的boost :: copy_exception
来的异常复制到 exception_ptr
,我失去了类型信息。看看下面code:
When I use boost::copy_exception
to copy an exception to an exception_ptr
, I lose type information. Take a look at the following code:
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;
}
}
在此,我得到以下的输出:
From this, I get the following output:
N5boost16exception_detail10clone_implISt9exceptionEE
Dynamic exception type: boost::exception_detail::clone_impl<std::exception>
std::exception::what: N5boost16exception_detail10clone_implISt9exceptionEE
所以基本上的boost :: copy_exception
静态复制它得到的说法。
So basically boost::copy_exception
statically copied the argument it got.
如果我把我的异常与的boost ::函数enable_current_exception
来代替,这样这个问题就迎刃而解了。
This problem is solved if I throw my exception with boost::enable_current_exception
instead, like this.
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
库抛出。在这种情况下,有什么办法把例外成 exception_ptr
除了一个,并使用的boost ::捕捉每一种可能的例外之一copy_exception
每一个?
The problem with this is that sometimes the exceptions are thrown by a library that does not use boost::enable_current_exception
. In this case, is there any way to put the exception into an exception_ptr
apart from catching each kind of possible exception one by one and use boost::copy_exception
on each one?
推荐答案
这是由设计,和你的分析是正确的:静态类型使用,而不是动态类型。事实上,为了避免这种情况的惊喜,的boost :: copy_exception
成为的std :: make_exception_ptr
时,导致到C的过程++ 11。这样一来,它更清晰的 current_exception(Boost的版本或C ++ 11一个人是否)
是正确的事情,以使用正确捕获,那么,当前异常。我强烈建议使用 BOOST_THROW_EXCEPTION
或的boost :: throw_exception
,当涉及到使用Boost.Exception启用,至少例外的code。
This is by design, and your analysis is correct: the static type is used, not the dynamic type. In fact, to avoid this surprise, boost::copy_exception
became std::make_exception_ptr
during the process that led to C++11. That way, it's clearer that current_exception
(whether the Boost version or the C++11 one) is the correct thing to use to correctly capture, well, the current exception. I highly recommend using BOOST_THROW_EXCEPTION
, or at least boost::throw_exception
, when it comes to using Boost.Exception-enabled exceptions in your code.
当涉及到第三方code,没有比你已经提到的,或其他一些道德等同(如的dynamic_cast
-ing其他的解决办法不同的叶类将异常类型层次结构或层次结构,或的typeid
滥用)。
When it comes to third-party code, there is no solution other than the one you already mentioned, or some other moral equivalent (like dynamic_cast
-ing to the different leaf classes that make up the exception type hierarchy or hierarchies, or typeid
abuse).
在这方面的异常处理是相同的,与一种或多态类型的多层次结构的工作,你正在试图在这种情况下的操作是一个虚拟拷贝,也称为克隆:或者您的code是侵入旨在支持(使用如 BOOST_THROW_EXCEPTION(五时)就是如此;
而不是扔ë;
),或者你会痛苦地走继承树。请注意,您至少可以重构痛苦逼到一个网站,这样你会落得例如
In this respect exception handling is the same as working with one or more hierarchy of polymorphic types, and the operation you're attempting in this case is a virtual copy, also known as cloning: either your code is intrusively designed to support that (as is the case when using e.g. BOOST_THROW_EXCEPTION(e);
instead of throw e;
), or you're going to painfully walk the inheritance tree. Note that you can at least refactor that pain into just one site, such that you'd end up with e.g.
try {
third_party_api();
} catch(...) {
ptr = catch_exceptions_from_api();
}
这篇关于为什么我失去类型信息使用boost :: copy_exception什么时候?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!