I am changing some code in a legacy code base. Inside this code there is an often repeated pattern that looks like the following:
std::stringstream ss;
ss << ...;
throw MyCustomException(ss.str());
Since I am modifying the code anyways I wanted to make something like the following:
throw MyCustomException() << ...;
effectively removing the need for the std::stringstream.
I found a solution:
struct MyCustomException: public std::runtime_error
{
MyCustomException(const std::string& what_arg="")
: std::runtime_error(what_arg)
{
}
#if 0
template<typename T>
friend
MyCustomException operator<<(MyCustomException e, const T& obj)
{
std::stringstream ss;
ss << e.what();
ss << obj;
return MyCustomException(ss.str());
}
#else
template<typename T>
MyCustomException operator<<(const T& obj)
{
std::stringstream ss;
ss << what();
ss << obj;
return MyCustomException(ss.str());
}
#endif
};
Both solutions (#if ... #endif) work, but since everything is by value, a lot of copies of the exception object are created before it is thrown. Changing the signature to MyCustomException& e produces a ton of compile time errors (why?).
The whole problem is further complicated by the fact that I am bound to an old GCC revision that only supports C++03. So no fancy C++1[147] stuff here!
Is there a better way to make my desired functionality (throw MyCustomException() << ...;) work without the creation of the many temporary copies when throwing an exception?