I want to create a number of exception types which derive from std::runtime_error and I want them to have stringstream type functionality. I’ve therefore created an exception class which composes a std::stringstream and which derives from std::runtime_error:
template<typename T>
class error_stream : public std::runtime_error
{
public:
error_stream() :
std::runtime_error(""), ss(std::make_shared<std::basic_stringstream<T>> ())
{
}
~error_stream() throw()
{
}
template <typename T>
error_stream & operator << (const T & t)
{
*ss << t;
return *this;
}
virtual const char * what() const throw()
{
get_str(s_, ss->str());
return s_.c_str();
}
protected:
template <typename T>
void get_str(std::basic_string<char> & s_, const std::basic_string<T> & str) const
{
s_ = str;
}
template<>
void get_str(std::basic_string<char> & s_, const std::basic_string<wchar_t> & str) const
{
std::basic_string<char> ret(str.begin(), str.end());
s_ = ret;
}
protected:
std::shared_ptr<std::basic_stringstream<T>> ss;
mutable std::basic_string<char> s_;
};
And I’ve created a more specific exception type which in turn derives from this error_stream exception:
template<typename T>
class w32file_exception : public w32utils::error_stream<T>
{
public:
w32file_exception() : error_stream<T>() {}
};
However, I’ve encountered something I don’t understand here, because when I throw a w32file_exception I actually can only catch it as it’s parent error_stream. Can anyone see what I’m doing wrong?
try
{
throw w32file_exception<char>() << "test";
}
catch ( w32file_exception<char> & e )
{
ASSERT_PASSED;
}
catch ( error_stream<char> & e )
{
std::cout << e.what() << std::endl; // Why do I end up here?
}
What exactly does your
throwlook like? Are you using youroperator<<before calling throw, like this:Then the answer is, that your
operator<<returns anerror_streamand now32file_exceptionand so the type of the thrown exception iserror_stream.You could solve this problem this way:
But then you loose the ability to catch every
error_streamexception because it is a new Type for everyDERIVEDtype.