Как отбросить исходное исключение, сохраненное в std :: exception_ptr с boost :: future? - PullRequest
0 голосов
/ 27 августа 2018

Это минимальный пример кода, как исключение перемещается с использованием 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.

1 Ответ

0 голосов
/ 28 августа 2018

Кажется, работает с https://www.boost.org/doc/libs/1_68_0/libs/exception/doc/boost-exception.html

Я не должен был использовать std :: exception_ptr с Boost.Thread.

Существует также закрытый (не исправить) билет на эту функцию: https://svn.boost.org/trac10/ticket/9710

И этот вопрос, как можно выполнить преобразование: Преобразование std :: exception_ptr в boost :: exception_ptr

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...