Перехват исключения Boost и извлечение его сообщения

0

Я пишу функцию wd_sprintf, чтобы предоставить API-интерфейс sprintf. Под обложками используется библиотека ускорения.

Если пользователь wd_sprintf кодирует строку формата, boost::format выдаст исключение. Я хотел бы, чтобы моя функция перехватывала исключение, переупаковывает его в сообщении, которое идентифицирует wd_sprintf как локус ошибки и повторяет исключение.

Я не могу понять, что поймать и как извлечь сообщение.

// wd_sprintf(pattern [,args...]):                                                                                                                                              
//                                                                                                                                                                              
// This creates a temporary boost::format from pattern, and calls                                                                                                               
// wd_sprintf_r() to recursively extract and apply arguments.                                                                                                                   
#include <boost/exception/all.hpp>
class wd_sprintf_exception : std::runtime_error {
public:
    wd_sprintf_exception(string const& msg : std::runtime_error(msg) {}
};

template <typename... Params>
string
wd_sprintf (const string &pat, const Params&... parameters) {
    try {
        boost::format boost_format(pat);
        return wd_sprintf_r(boost_format, parameters...);
    }
    catch (boost::exception e) {
        const string what = string("wd_sprintf: ") + string(e.what());
        throw wd_sprintf_exception(what);
    }
}

Конечно, это получает ошибку компиляции, потому что boost :: exception является абстрактным.

(Я был на нескольких сайтах и страницах, включая тот, чей заголовок был похож, но который был заполнен операторами "<<", вставляющими в вызов функции, конструкциями шаблонов, такими как boost::get_error_info<my_tag_error_info>(e), и, как правило, гораздо сложнее, чем я подозреваю, действительно необходимо. Мне просто нужно, чтобы выше работали.)

  • 2
    Вы всегда должны ловить по ссылке . boost::exception (и стандартная библиотека C ++) были разработаны таким образом.
Теги:
exception
try-catch
boost

1 ответ

0

Вы не можете иметь автоматическую переменную абстрактного типа. Однако вы можете иметь ссылку или указатель на один. Причина этого заключается в том, что компилятор не имеет возможности точно знать, какой производный тип является фактически переменной, поэтому он не знает, сколько места выделяется для него или какой конструктор экземпляра класса использовать.

Когда вы поймаете boost::exception по значению, как вы это делаете, компилятор должен сделать локальную копию этого в вашем блоке catch; которой у него недостаточно информации!

В вашем конкретном случае лучшим решением является поиск ссылки на исходное исключение.

Что касается catching exceptions из Boost.Format, он генерирует исключения, полученные из boost::io::format_error, который получен из std::exception, not boost::exception. Вы должны поймать boost::io::format_error.

  • 0
    Это полезно, и отлов по ссылке устраняет ошибку компилятора. Но я до сих пор не знаю, как извлечь сообщение из е . ( e.what() не работает, потому что boost::exception не имеет what() )
  • 0
    Ой, мой плохой; обновил мой ответ.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню