【问题标题】:How to rethrow the original exception stored by an std::exception_ptr with a boost::future?如何用 boost::future 重新抛出 std::exception_ptr 存储的原始异常?
【发布时间】: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


【解决方案1】:

它似乎适用于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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-25
    • 2014-03-27
    • 2011-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    相关资源
    最近更新 更多