Exception Streams in C++
Here's a short but handy C++ Snippet. I was looking for a way to quickly generate runtime exceptions with useful information about the current program state. My process was:
- Create a string stream
- Build the message
- Throw the exception using the string from the stream
I felt like this was particularly cumbersome and quite annoying, especially for doing things like string parsing or SQL because there are a lot of places in the code where error checking is required.
In any case, I came up with this simple little class tempate which sits in a single header file and is included in the cpp file where it is to be used.
#ifndef _UTILITY_EXCEPTIONSTREAM_H_ #define _UTILITY_EXCEPTIONSTREAM_H_ #include #include namespace utility { /// used to simplify the process of generating an exception message /** * Derives from stringstream so provides an ostream interface, but throws * an exception with the contents of the string when the object is destroyed * * \tparam Exception_t must be an exception type which accepts a * const char* in it's constructor * */ template class ExceptionStream : public std::stringstream { public: ~ExceptionStream() { throw Exception_t( str().c_str() ); } std::ostream& operator()() { return *this; } }; typedef ExceptionStream ex; } /* namespace utility */ #endif /* EXCEPTIONSTREAM_H_ */
Usage is like this:
ex fExp; fExp = evalf( m_expression["radius"].subs(m_x == iRadius)); if( is_a(fExp) ) radius= ex_to(fExp).to_double(); else { utility::ex()() << "GiNaC failed to parse radius expression: " << fExp; }
Here I'm using GiNaC to parse a string into a mathematical expression. If the process fails I want to throw a runtime exception (typedef'ed as utility::ex).
The class derives from string stream so it works just like a string stream… building a string by catting together the RHS of all the string operators. The magic is that the destructor for the class throws an exception. The message for the exception is the string that was built.
It's a very handy time saver… though I'm not sure if it's actually safe to use. If the destructor throws an exception, is the object memory still freed?
Comments
Comments powered by Disqus