【发布时间】:2019-02-02 05:44:48
【问题描述】:
这是如何使用 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。
【问题讨论】:
-
这里有很多代码
-
我知道您编写了这段代码,但它不起作用。但在将其发布到此处之前,请生成minimal reproducible example。 90% 以上的上述代码看起来与您的问题无关;删除内容,直到剩下大约 5 行和相同的错误。
-
sry 伙计们,我已经修改了原始帖子以显示实际问题。
-
好吧,在原始代码中我不能只调用 throw。这是一个修改后的示例来演示错误。我必须以某种方式存储异常并稍后重新抛出它。不知道std::exception_ptr是不是存储异常的正确方式,但是既然异常不必继承std::exception,那我非得用吗?
标签: c++ multithreading boost boost-thread