Is it possible to write a method that takes a stringstream and have it look something like this,
void method(string str)
void printStringStream( StringStream& ss)
{
method(ss.str());
}
And can be called like this
stringstream var;
printStringStream( var << "Text" << intVar << "More text"<<floatvar);
I looked up the << operator and it looks like it returns a ostream&
object but I'm probably reading this
wrong or just not implementing it right.
Really all I want is a clean way to concatenate stuff together as a string and pass it to a function. The cleanest thing I could find was a stringstream object but that still leaves much to be desired.
Notes:
I can't use much of c++11
answers because I'm running on Visual Studio 2010 (against my will, but still)
I have access to Boost
so go nuts with that.
I wouldn't be against a custom method as long as it cleans up this mess.
Edit:
With @Mooing Duck's answer mixed with @PiotrNycz syntax I achieved my goal of written code like this,
try{
//code
}catch(exception e)
{
printStringStream( stringstream() << "An exception has occurred.\n"
<<" Error: " << e.message
<<"\n If this persists please contact "<< contactInfo
<<"\n Sorry for the inconvenience");
}
This is as clean and readable as I could have hoped for.
Hopefully this helps others clean up writing messages.
For ease of writing objects that can be inserted into a stream, all these classes overload
operator<<
onostream&
. (Operator overloading can be used by subclasses, if no closer match exists.) Theseoperator<<
overloads all returnostream&
.What you can do is make the function take an
ostream&
anddynamic_cast<>
it tostringstream&
. If the wrong type is passed in,bad_cast
is thrown.Note:
static_cast<>
can be used, it will be faster, but not so bug proof in the case you passed something that is not astringstream
.Just to add to the mix: Personally, I would create a stream which calls whatever function I need to call upon destruction:
It is worth noting that the first object sent to the temporary has to be of a specific set of types, namely one of those, the class
std::ostream
knows about: Normally, the shift operator takes anstd::ostream&
as first argument but a temporary cannot be bound to this type. However, there are a number of member operators which, being a member, don't need to bind to a reference! If you want to use a user defined type first, you need to extract a reference temporary which can be done by using one of the member input operators.Make your wrapper over std::stringstream. In this new class you can define whatever
operator <<
you need:Since you know you've got a
stringstream
, just cast the return value:Ah, took me a minute. Since
operator<<
is a free function overloaded for all ostream types, it doesn't return astd::stringstream
, it returns astd::ostream
like you say.Now clearly, general
ostream
s don't have a.str()
member, but they do have a magic way to copy one entire stream to another:Here's a link to the full code showing that it compiles and runs fine http://ideone.com/DgL5V
EDIT
If you really need a string in the function, I can think of a few solutions:
First, do the streaming seperately:
Second: copy the stream to a string (possible performance issue)
Third: make the other function take a stream too