Why Was Std::Strstream Deprecated

Why was std::strstream deprecated?

The strstream returned a char * that was very difficult to manage, as nowhere was it stated how it had been allocated. It was thus impossible to know if you should delete it or call free() on it or do something else entirely. About the only really satisfactory way to deallocate it was to hand it back to the strstream via the freeze() function. This was sufficiently non-obvious, that lots of people got it wrong. The stringstream returns a string object which manages itself, which is far less error prone.

There was also the issue of having to use ends to terminate the string, but I believe the deallocation problem was the main reason for deprecation.

How can I get the same strstream functionality now that's deprecated?

The standard library doesn't provide that functionality. However, Boost does with its generic streams and array sources/sinks.

Boost Generic Stream

Boost Array Devices

char buff[size];
boost::stream<boost::array_sink> out(buff, size);
out << "Hello, world!";

(Code untested)

Was strstream ever part of the standard?

Yes, they always were (since 1998) and are part of the standard, but they are deprecated (and always have been, since 1998).

The natural question that follows is: why were they added as deprecated? I can only speculate here, but there is no alternative where you can manage your own buffer, and you can not access the string of stringstream directly, so this template is without a good alternative. The committee will surely be open for a new proposal to fill this gap (that is, control the buffer), but undeprecating strstream is likely a no-no.

What should I use instead of std::ostrstream?

You could use std::ostringstream. Similarly, instead of std::istrstream you should use std::istringstream. You need to include the <sstream> header for these classes.

You could also see this question which explains why strstream was deprecated.

How will std::spanstream usually be used in C++?

They are intended to be a near drop-in replacement for strstream (except with proper bounds checking). As such, they will have the exact same use cases. When you have an existing buffer that you want to stream into/outof.

The ability to move a std::string into stringstreams added in C++20 eliminated the use case when the existing buffer is in a std::string. But sometimes you just have a naked char const* with a known length.

What I can use instead of strstream::freeze?

You don't need freeze() in case of std::ostringstream - the necessity of calling this function was actually one of the reasons why strstream got deprecated in the first place. Because of its design (returning char* from str()) it wasn't clear who should clean the buffer that strstream holds and freeze() had to be used to signal that you want strstream itself to do it after every call to str() - in case of std::ostringstream you don't need to worry about this as str() returns a copy of the std::string.

A better replacement for istrstream?

Continue using istrstream for the time being. It likely won't be removed until either P0448 (using std::span<char> as the source/destination of a stream buffer) or P0408 (the ability to move data into/outof stringstreams) is adopted by the standard. Either of those would serve your needs well.

That being said, if all you're trying to do is get substrings between \ns, it would be far more efficient (even with the above proposals) to just use a regex search. Or just a regular search, since you're just looking for \n. That would give you a pair of iterators that represents a line. Using iostreams for line-by-line processing of an already-loaded character buffer is overkill and will never be as efficient as the alternative.

strstreambuf Deprecated in Visual C++ 2010 - is it still possible to link to it?

The reason you can't link a C++ library built in VS2005 with VS2010 is not because of strstreambuf being deprecated or not, but because the runtime library binaries changed for the new compiler version. Part of it is that several parts of the C++ standard library have been changed over to being header only.

It's a really, really bad idea to link C++ code built with one compiler with a runtime library for another compiler; you really want to make sure that you build everything that gets statically linked with the same compiler version as mayhem is likely to ensue otherwise.

Your best (only) hope is to get the supplier of said 3rd party library to cough up a version built with VS2010.



Related Topics



Leave a reply



Submit