c++ - 将 std::exception_ptr 转换为 boost::exception_ptr

标签 c++ boost c++11

我想使用 boost::promise::set_exception() 需要一个 boost::exception_ptr。问题是 boost:exception_ptr 似乎只有在我用 enable_current_exception 包裹所有我的抛出时才能正常工作,我想避免这种情况。 (无论如何,我无法为第 3 方图书馆做到这一点。) 我在整个代码中使用 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 不是一个选项(至少目前是这样)

如果您知道使 boost::exception_ptr 依赖于 gcc 4.8 编译器支持而不是 enable_current_exception 的方法,这也是一个可接受的解决方案

最佳答案

不幸的是,我认为这是不可能的。但是,我可以为您提供三种可能的解决方案,按方便程度排序:

1。捕获一个 std::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;
    }

}

这会打印 "std::exception" 而不是 "hello world",因为来自派生类的信息(在这种情况下,std::runtime_error) 将被切掉。

2。直接抛出std::exception_ptr

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 block 为代价。如果错误处理是在中央位置完成的,可能会显示一个对话框,我会选择这个解决方案。在 boost 作者添加一个从 std::exception_ptrboost::exception_ptr 的构造函数之前,恐怕这已经很好了。

使用 boost::packaged_task 而不是 boost::promise

如果您可以接受使用 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()

关于c++ - 将 std::exception_ptr 转换为 boost::exception_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22010388/

相关文章:

c++ - 正确使用递归

c++ - 错误 : default argument given for parameter 1

python - 使用多个 Python 版本构建 Boost

c++ - boost IPC Message_Queue try_receive 抛出 interprocess_exception::library_error

c++ - 为什么在这种情况下 c++ 模板参数推导失败?

C++ 函数返回对数组的引用

c++ - 将 minutes::rep 转换为 hours::rep

c++ - 如何有条件地使用 boost MPL 添加?

c++ - const char * 和文字字符串有什么区别?

C++ 网格在不应该的时候变得动画化