Is there a canonical / public / free implementations variant of std::stringstream
where I don't pay for a full string copy each time I call str()
? (Possibly through providing a direct c_str()
member in the osteam class?)
I've found two questions here:
And "of course" the deprecated std::strstream
class does allow for direct buffer access, although it's interface is really quirky (apart from it being deprecated).
It also seems one can find several code samples that do explain how one can customize std::streambuf
to allow direct access to the buffer -- I haven't tried it in practice, but it seems quite easily implemented.
My question here is really two fold:
std::[o]stringstream
(or, rather, basic_stringbuf
) does not allow direct buffer access, but only access through an (expensive) copy of the whole buffer?Note: The performance hit of the copy that str()
makes is very measurable(*), so it seems weird to have to pay for this when the use cases I have seen so far really never need a copy returned from the stringstream. (And if I'd need a copy I could always make it at the "client side".)
(*): With our platform (VS 2005), the results I measure in the release version are:
// tested in a tight loop:
// variant stream: run time : 100%
std::stringstream msg;
msg << "Error " << GetDetailedErrorMsg() << " while testing!";
DoLogErrorMsg(msg.str().c_str());
// variant string: run time: *** 60% ***
std::string msg;
((msg += "Error ") += GetDetailedErrorMsg()) += " while testing!";
DoLogErrorMsg(msg.c_str());
So using a std::string
with +=
(which obviously only works when I don't need custom/number formatting is 40% faster that the stream version, and as far as I can tell this is only due to the complete superfluous copy that str()
makes.
The clear() member function is inherited from ios and is used to clear the error state of the stream, e.g. if a file stream has the error state set to eofbit (end-of-file), then calling clear() will set the error state back to goodbit (no error). For clearing the contents of a stringstream , using: m. str("");
Absolutely! Make sure that you pass it by reference, not by value.
To use stringstream, we need to include sstream header file.
To use stringstream class in the C++ program, we have to use the header <sstream>. For Example, the code to extract an integer from the string would be: string mystr(“2019”); int myInt; stringstream (mystr)>>myInt; Here we declare a string object with value “2019” and an int object “myInt”.
I will try to provide an answer to my first bullet,
Is there any deeper reason why
std::ostringstream
does not allow direct buffer access
Looking at how a streambuf
/ stringbuf
is defined, we can see that the buffer character sequence is not NULL terminated.
As far as I can see, a (hypothetical) const char* std::ostringstream::c_str() const;
function, providing direct read-only buffer access, can only make sense when the valid buffer range would always be NULL terminated -- i.e. (I think) when sputc would always make sure that it inserts a terminating NULL after the character it inserts.
I wouldn't think that this is a technical hindrance per se, but given the complexity of the basic_streambuf
interface, I'm totally not sure whether it is correct in all cases.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With