Converting std::exception_ptr to boost::exception_ptr

boost, c++, c++11

Solution

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

1. Catch a 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;
    }

}

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

2. Throw the std::exception_ptr directly

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;
        }
    }

}

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.

Use boost::packaged_task instead of boost::promise

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;
    }

}

Prints `"hello world"` and allows you to use `fut.then()`.

Problem

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(); } } } ``` Do you have any idea how to do that? Context: I need `boost::future::then()`, so using a `std::promise` is unfortunately not an option (at least at the moment) 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

Original source