我想使用boost::promise::set_exception()那个期待的boost::exception_ptr.问题是,boost:exception_ptr只有当我把所有的投掷包裹起来enable_current_exception并且我想避免这种情况时,似乎才能正常工作.(我不能够做到这一点的第三方库反正)我用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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
你知道怎么做吗?
语境:
我需要boost::future::then(),所以使用a std::promise很遗憾不是一种选择(至少在目前)
如果你知道一种boost::exception_ptr依赖gcc 4.8编译器支持的方法enable_current_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;
}
}
Run Code Online (Sandbox Code Playgroud)
这将打印"std::exception"而不是"hello world",因为来自派生类(在本例中为std::runtime_error)的信息将被切掉。
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
此版本打印,尽管需要额外/块"hello world"的成本。如果错误处理是在中心位置完成的,可能会显示一个对话框,我会选择这个解决方案。恐怕在 boost 作者添加一个构造函数 from to之前,这已经是最好的了。trycatchstd::exception_ptrboost::exception_ptr
如果您可以接受使用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;
}
}
Run Code Online (Sandbox Code Playgroud)
打印"hello world"并允许您使用fut.then()。