为什么我失去类型信息使用boost :: copy_exception什么时候? [英] Why do I lose type information when using boost::copy_exception?

查看:153
本文介绍了为什么我失去类型信息使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆