将std :: exception_ptr转换为boost :: exception_ptr [英] Converting std::exception_ptr to boost::exception_ptr
问题描述
我想使用期望boost::exception_ptr
的boost::promise::set_exception()
.问题是,只有当我用enable_current_exception
包装所有 all 时,boost:exception_ptr
似乎才能正常工作,并且我想避免这种情况. (无论如何,我将无法对第三方库进行此操作.)
我在整个代码中都使用std::exception_ptr/std::current_exception
,因此我正在寻找一种在期望boost:exception_ptr
的地方传递std::exception_ptr
的方法.
可以执行以下操作但可以编译的东西:
I want to use boost::promise::set_exception()
that expects a boost::exception_ptr
. The problem is that boost:exception_ptr
seems to work correctly only if I wrap all my throws with enable_current_exception
and I want to avoid that. (I wouldn't be able to do that for 3rd party libraries anyway.)
I use std::exception_ptr/std::current_exception
throughout my code, so I am looking for a way to pass std::exception_ptr
where a boost:exception_ptr
is expected.
Something that does the following, but compiles:
boost::exception_ptr convert(std::exception_ptr ex) {
try {
std::rethrow_exception(ex);
}
catch(auto& ex) {
try {
throw boost::enable_current_exception(ex);
}
catch (...) {
return boost::current_exception();
}
}
}
您是否知道该怎么做?
上下文:
我需要boost::future::then()
,所以不幸的是(至少目前)使用std::promise
不是一个选择
I need boost::future::then()
, so using a std::promise
is unfortunately not an option (at least at the moment)
如果您知道一种使boost::exception_ptr
依赖gcc 4.8编译器支持而不是enable_current_exception
的方法,那也是可以接受的解决方案
If you know a way to make boost::exception_ptr
to rely on gcc 4.8 compiler support instead of enable_current_exception
that would be an acceptable solution, as well
推荐答案
不幸的是,我认为这是不可能的.但是,我可以为您提供三种可能的解决方案,按便利性排序:
Unfortunately, I don't think this is possible. However, I can offer you three possible solutions, sorted by convenience:
boost::exception_ptr convert(std::exception_ptr ex)
{
try {
std::rethrow_exception(ex);
} catch (const std::exception& e) {
try {
throw boost::enable_current_exception(e);
} catch (...) {
return boost::current_exception();
}
} catch (...) {
try {
throw boost::enable_current_exception(std::runtime_error("Unknown exception."));
} catch (...) {
return boost::current_exception();
}
}
}
int main()
{
std::exception_ptr sep;
try {
throw std::runtime_error("hello world");
} catch (...) {
sep = std::current_exception();
}
boost::exception_ptr bep = convert(sep);
try {
boost::rethrow_exception(bep);
} catch (const std::exception& e) {
std::cout << e.what() << std::endl;
}
}
这将打印"std::exception"
而不是"hello world"
,因为来自派生类(在本例中为std::runtime_error
)的信息将被切掉.
This prints "std::exception"
instead of "hello world"
, since information from derived classes (in this case, std::runtime_error
) will be sliced away.
boost::exception_ptr convert(std::exception_ptr ex)
{
try {
throw boost::enable_current_exception(ex);
} catch (...) {
return boost::current_exception();
}
}
int main()
{
std::exception_ptr sep;
try {
throw std::runtime_error("hello world");
} catch (...) {
sep = std::current_exception();
}
boost::exception_ptr bep = convert(sep);
try {
boost::rethrow_exception(bep);
} catch (const std::exception_ptr& ep) {
try {
std::rethrow_exception(ep);
} catch (const std::exception& e) {
std::cout << e.what() << std::endl;
}
}
}
此版本可打印"hello world"
,尽管要付出额外的try
/catch
块的代价.如果错误处理是在中央位置进行的,可能会显示一个对话框,那么我将寻求该解决方案.恐怕直到提升作者将std::exception_ptr
到boost::exception_ptr
的构造函数添加进来之前,恐怕还是一样.
This version prints "hello world"
, albeit at the cost of an extra try
/catch
block. If error handling is done at a central location, maybe displaying a dialog box, I'd go for this solution. Until the boost authors add a constructor from std::exception_ptr
to boost::exception_ptr
, that's as good as it gets, I'm afraid.
如果可以继续使用packaged_task
,则此解决方案有效:
If you can live with using packaged_task
, this solution works:
#define BOOST_THREAD_VERSION 4
#include <boost/thread.hpp>
int main()
{
boost::packaged_task<int()> pt([] () -> int {
throw std::runtime_error("hello world");
});
boost::future<int> f1 = pt.get_future();
boost::future<int> f2 = f1.then([] (boost::future<int> f) {
return f.get() + 1;
});
boost::thread(std::move(pt)).detach();
try {
int res = f2.get();
} catch (const std::runtime_error& e) {
std::cout << e.what() << std::endl;
}
}
打印"hello world"
并允许您使用fut.then()
.
这篇关于将std :: exception_ptr转换为boost :: exception_ptr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!