将std :: exception_ptr转换为boost :: exception_ptr [英] Converting std::exception_ptr to boost::exception_ptr

查看:116
本文介绍了将std :: exception_ptr转换为boost :: exception_ptr的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用期望boost::exception_ptrboost::promise::set_exception().问题是,只有当我用enable_current_exception包装所有 all 时,boost:exception_ptr似乎才能正常工作,并且我想避免这种情况. (无论如何,我将无法对第三方库进行此操作.) 我在整个代码中都使用std::exception_ptr/std::current_exception,因此我正在寻找一种在期望boost:exception_ptr的地方传递std::exception_ptr的方法. 可以执行以下操作但可以编译的东西:

I want to use boost::promise::set_exception() that expects a boost::exception_ptr. The problem is that boost:exception_ptr seems to work correctly only if I wrap all my throws with enable_current_exception and I want to avoid that. (I wouldn't be able to do that for 3rd party libraries anyway.) I use std::exception_ptr/std::current_exception throughout my code, so I am looking for a way to pass std::exception_ptr where a boost:exception_ptr is expected. Something that does the following, but compiles:

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不是一个选择

I need boost::future::then(), so using a std::promise is unfortunately not an option (at least at the moment)

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

If you know a way to make boost::exception_ptr to rely on gcc 4.8 compiler support instead of enable_current_exception that would be an acceptable solution, as well

推荐答案

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

Unfortunately, I don't think this is possible. However, I can offer you three possible solutions, sorted by convenience:

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)的信息将被切掉.

This prints "std::exception" instead of "hello world", since information from derived classes (in this case, std::runtime_error) will be sliced away.

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_ptrboost::exception_ptr的构造函数添加进来之前,恐怕还是一样.

This version prints "hello world", albeit at the cost of an extra try/catch block. If error handling is done at a central location, maybe displaying a dialog box, I'd go for this solution. Until the boost authors add a constructor from std::exception_ptr to boost::exception_ptr, that's as good as it gets, I'm afraid.

如果可以继续使用packaged_task,则此解决方案有效:

If you can live with using packaged_task, this solution works:

#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().

这篇关于将std :: exception_ptr转换为boost :: exception_ptr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆