这是一个最小的代码示例,如何使用std :: exception_ptr:来处理异常。
#include <iostream>
#include <boost/thread.hpp>
#include <boost/optional.hpp>
#include <boost/variant.hpp>
int main() {
try
{
throw std::runtime_error("Error!");
}
catch (...)
{
boost::optional<boost::variant<int, std::exception_ptr>> v(std::move(std::current_exception()));
boost::promise<int> p;
boost::future<int> f = p.get_future();
try
{
std::rethrow_exception(std::move(boost::get<std::exception_ptr>(std::move(v.get()))));
}
catch (...)
{
p.set_exception(std::move(std::current_exception()));
}
try
{
f.get();
}
catch (const std::exception &e)
{
// This is what I would like to see:
std::cerr << "Error: " << e.what() << std::endl;
}
catch (...)
{
// This is what I get instead:
std::cerr << "Unknown error" << std::endl;
}
}
return 0;
}
我想保留实际的对象std :: runtime_error并将其扔到最后的f.get()语句中。相反,我得到了一个未知异常,它不是从std :: exception派生的。 当我删除最终的catch(...)语句时,得到以下输出:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<std::__exception_ptr::exception_ptr>'
我想避免任何克隆/复制操作。我想保留我的std :: runtime_error实例并将其移动到结尾(最后的f.get()调用)。 如果有比std :: exception_ptr更好的方法来存储任何异常,请告诉我,我将改用它。 Folly使用类模板folly :: exception_wrapper,但我不知道其他任何标准类型。
您可以在此处检出原始项目的文件:https://github.com/tdauth/cpp-futures-promises/tree/master/src/advanced 需要不同的重新抛出,因为我使用了包装类型Try和方法Promise :: tryComplete。
答案 0 :(得分:0)
它似乎可以与https://www.boost.org/doc/libs/1_68_0/libs/exception/doc/boost-exception.html
一起使用我不应该在Boost.Thread中使用std :: exception_ptr。
此功能也有一张封闭(无法修复)的票证:https://svn.boost.org/trac10/ticket/9710
这个问题是如何进行转换的:Converting std::exception_ptr to boost::exception_ptr