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

1

11

<spanstream> will debut in C++23 (see cppreference). According to the proposal, they are string-streams with std::span based buffers.

My questions are:

  • Does std::spanstream have somewhat equivalent uses of the old std::strstream (or strstream deprecated in C++ 98)?
  • What will be the benefits of using them after the full release of C++ 23?
Babara answered 10/6, 2021 at 15:36 Comment(7)
std::strstream? What is it? I would say it is a stream adapter to any sequenced data, like std::istringstream is a stream adapter to std::string with an advantage of not coping strings.Recusancy
There have never been a std::strstream but I guess you mean the old pre-standard (and therefore not in any namespace) strstream?Gruber
... I imagine with spanstream, it can finally be removed after more than 20 years of deprecationDowngrade
@DesmondGold Thanks for the link. It's weird to see that in the actual standard library, and that it has only bee deprecated and not removed yet. IMO it shouldn't be in there at all.Gruber
@Someprogrammerdude: Why shouldn't it be there? It's useful to be able to stream into/outof existing buffers, and strstream is the only way to do that.Pith
From skimming the paper it looks like it is intended to offer the same thing std::stringstream does, but instead of having a string object you can't manage, std::spanstream will use a span(buffer) that you give it for the stream contents.Chartist
@Someprogrammerdude this en.cppreference.com/w/cpp/io/strstreamCarsoncarstensz
P
15

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.

Pith answered 10/6, 2021 at 15:42 Comment(18)
And how is it different from std::format_to?Veiling
@AyxanHaqverdili it's a stream, not an iterator. Sometimes you have code that was written expecting to be couted (or cined)Flipper
@Flipper std::format falls back to operator<<, right? I don't see how the same buffer cannot be used with format_to.Veiling
@AyxanHaqverdili: You mean besides proper bounds checking? Also, doesn't the operator<< fallback have to allocate memory for the stream to write into? Effectively creating a stringstream, then copying from that into the output iterator?Pith
@Nicol we have format_to_n for bounds checking.Veiling
I am not familiar with the fallback API tbh, but moving forward code should be written for the "format" API, right? I am confused if we are trying to deprecate the iostreams, or encourage them.Veiling
@AyxanHaqverdili: "I am confused if we are trying to deprecate the iostreams, or encourage them." Why does it have to be either/or? Also, format only works for outputting; it does nothing for inputting.Pith
@NicolBolas Well, adding duplicate functionality is hardly useful. The part of the standard library that I dread the most is iostreams, so I might be a bit biased. I would hope the next step would be adding a format-like API for input/file-handling.Veiling
@AyxanHaqverdili std::format doesn't have an operator<< fallback.Latonya
@Latonya here fmt author mentioned that fmt falls back to operator<<, so I was recalling that. Perhaps it didn't make its way to C++20, or maybe they removed it down the road. Thank you for pointing out.Veiling
fmt does, but the std one doesn't (this sort of fallback is an ODR-violation magnet)Latonya
@Latonya what do you mean by "ODR-violation management"? Would it be an ODR violation for std::format to fallback on operator<<?Veiling
@AyxanHaqverdili: He said "magnet." As in, it attracts ODR violations, because in one place of the code, your format call could call operator<<, while in another place, it'd call your proper overload.Pith
A prominent use case for strstream was that it could act over an existing buffer or create a dynamically growing one. The latter behavior is triggered by the default ctor while the former by constructing an strstream using an existing buffer. Can std::spanstream do this? All its constructors expect an existing buffer and span buffers are fixed (not dynamically growing). Given this restriction I'd call it a "nowhere near replacement"Embow
@LorahAttkins: If you're dynamically allocating memory, you use a stringstream. There is no point to using strstream for that. You can move into and outof stringstream, so there isn't even an allocation savings.Pith
@NicolBolas There's cases where stringstream is inadequate and has been a pain in Windows for years. Features of spanstream are way more restricted compared to strstream; strstream was created with two modes in mind, dynamic and fixed and spanstream is no replacement for that. That said, the added safety is appreciated.Embow
@LorahAttkins: "There's cases where stringstream is inadequate" No, that's a case where certain implementations of the type are not adequate to the user's needs. The standard does not require that any stream be able to support any particular data size. Microsoft's implementation of strstream could have been just as deficient as their implementation of stringstream. The fact that it wasn't isn't a problem that the C++ standard needs to solve. stringstream is the choice for when you need "dynamic" streams. If your implementation is insufficient, take it up with them.Pith
@NicolBolas My argument is that spanstream is not a drop in replacement since strstream was designed with the aforementioned "dual" mode in mind and spanstream has nothing to do with this. Peter mentions it in the proposal: A combination of external-fixed and internal-growing buffer allocation that strstreambuf provides is IMHO a doomed approach and very hard to use right.. It's less misleading to call it a "departure from that design" since that is what the introduction of spanstream signifies.Embow

© 2022 - 2024 — McMap. All rights reserved.