Can I cause an overflow of a stream stream without a stream object?

Suppose I want to throw with a string containing information about some object, but the implementation of the object has only overload for the stream operator ( << ), and not a string to a string. I want to do something like this:

 throw std::runtime_error("Error, encountered invalid value " + x); 

where x is an instance of a type that has ( << ) overloaded. The above does not work, however, since + not overloaded to a type compatible with const char* . If x was a string (or assigned to a string), this would work, but instead I have to do this:

 std::stringstream s; s << "Error, encountered invalid value " << x; throw std::runtime_error(s.str()); 

How can I get something short, like the first example, without adding overloads or custom functions. Does the standard library provide some features that will help here?

+5
source share
1 answer

You can delegate a function:

 template <typename T> std::string stream(const T& x) { std::ostringstream ss; ss << x; return ss.str(); } throw std::runtime_error("Error..." + stream(x)); 

What boost::lexical_cast also means:

 throw std::runtime_error("Error..." + boost::lexical_cast<std::string>(x)); 

Or you can use a temporary stream, which includes the need to do a translation, since operator<< usually returns only basic_ostream<char>& :

 throw std::runtime_error( static_cast<std::ostringstream&&>(std::ostringstream{} << "Error..." << x) .str() ); 

Or you can wrap this logic in a separate type, which when streaming converts the result to string , for fun:

 struct ToStrT { friend std::string operator<<(std::ostream& os, ToStrT ) { return static_cast<std::ostringstream&&>(os).str(); } }; constexpr ToStrT ToStr{}; throw std::runtime_error(std::ostringstream{} << "Error..." << x << ToStr); 
+4
source

All Articles