我想使用 boost::promise::set_exception()
需要一个 boost::exception_ptr
。问题是 boost:exception_ptr
似乎只有在我用 enable_current_exception
包裹所有我的抛出时才能正常工作,我想避免这种情况。 (无论如何,我无法为第 3 方图书馆做到这一点。)
我在整个代码中使用 std::exception_ptr/std::current_exception
,所以我正在寻找一种方法来传递 std::exception_ptr
,其中 boost:exception_ptr
是预期的。
执行以下操作但编译的东西:
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
不是一个选项(至少目前是这样)
如果您知道使 boost::exception_ptr
依赖于 gcc 4.8 编译器支持而不是 enable_current_exception
的方法,这也是一个可接受的解决方案
最佳答案
不幸的是,我认为这是不可能的。但是,我可以为您提供三种可能的解决方案,按方便程度排序:
1。捕获一个 std::exception
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
) 将被切掉。
2。直接抛出std::exception_ptr
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
block 为代价。如果错误处理是在中央位置完成的,可能会显示一个对话框,我会选择这个解决方案。在 boost 作者添加一个从 std::exception_ptr
到 boost::exception_ptr
的构造函数之前,恐怕这已经很好了。
使用 boost::packaged_task 而不是 boost::promise
如果您可以接受使用 packaged_task
,则此解决方案有效:
#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()
。
关于c++ - 将 std::exception_ptr 转换为 boost::exception_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22010388/