我想使用期望boost::promise::set_exception()
的{{1}}。问题是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();
}
}
}
,所以遗憾的是,使用boost::future::then()
不是一种选择(至少在目前)
如果您知道如何让std::promise
依赖gcc 4.8编译器支持而不是boost::exception_ptr
这是一个可接受的解决方案,那么
答案 0 :(得分:2)
不幸的是,我不认为这是可能的。但是,我可以为您提供三种可能的解决方案,按方便排序:
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
)的信息将被切掉。
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
的构造函数,这是好的,我很害怕。
如果您可以使用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()
。