Как сохранить тип исключения
От: Alexander Pazdnikov  
Дата: 21.06.11 05:33
Оценка:
Здравствуйте, Коллеги.

Помогите, пожалуйста, решить вопрос потери исходного типа исключения. Своих знаний не хватает.
Есть иерархия исключений. У базового класса определён operator<< для сохранения диагностической информации.
При кидании исключения с добавлением информации через operator<< изначальное исключение приводится к базовому, а хочется чтобы осталось то же самое.

P.S. boost::exception использовать не могу, компилятор в проекте gcc 3.2.3 слишком старый, не компилит boost::exception

прикрепил минимальный рабочий пример.

throw range_err(); //   работает нормально


а вот
throw range_err() << "Hello world!"; //  приводит тип исключения к base_error, а хочу чтобы остался range_err, как быть? 


#include <iostream>
#include <sstream>

using namespace std;

/**
 * Базовый класс исключений общ канальных драйверов
 */
struct base_error : public virtual std::exception
{
    template<typename T> base_error& operator<<(const T &str)
    {
        std::ostringstream os;
        os << m_what << str;
        m_what = os.str();
        return *this;
    };

    virtual ~base_error() throw () {};

    virtual const char * what() const throw() { return m_what.c_str(); }
    
protected:
    base_error() : std::exception() {}; // блокируем возможность кидать исключения base_error
private:
    std::string m_what;
};

struct run_error : public base_error {};

struct range_err : public run_error {}; ///< выход за пределы чего-нибудь (например, массива или вектора)

int main(int argc, char *argv[])
{
    // тут нормально
    try
    {
        throw range_err();
    }
    catch(const range_err &e)
    {
        cout << "Good" << endl;
    }


    // тут происходит подмена типа исключения
    try
    {
        throw range_err() << "Hello world!";
    }
    catch(const range_err &e)
    {
        // хочу поймать здесь 
        cout << "Good" << endl;
    }
    catch(const base_error &e)
    {
        // ловлю здесь 
        cout << "base_error, want range_error" << endl;
    }
    return 0;
}
exception operator<<
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.