7

<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?
PFee
  • 249
  • 2
  • 10
Desmond Gold
  • 1,517
  • 1
  • 7
  • 19
  • 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. – 273K Jun 10 '21 at 15:38
  • 1
    There have never been a `std::strstream` but I guess you mean the old pre-standard (and therefore not in any namespace) `strstream`? – Some programmer dude Jun 10 '21 at 15:39
  • 2
    ... I imagine with spanstream, it can finally be removed after more than 20 years of deprecation – StoryTeller - Unslander Monica Jun 10 '21 at 15:41
  • 1
    @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. – Some programmer dude Jun 10 '21 at 15:42
  • @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. – Nicol Bolas Jun 10 '21 at 15:43
  • 2
    From skimming [the paper](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0448r4.pdf) 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. – NathanOliver Jun 10 '21 at 15:43
  • @Someprogrammerdude this https://en.cppreference.com/w/cpp/io/strstream – Swift - Friday Pie Jun 10 '21 at 16:04

1 Answers1

11

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.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • And how is it different from [std::format_to](https://en.cppreference.com/w/cpp/utility/format/format_to)? – Aykhan Hagverdili Jun 10 '21 at 16:09
  • @AyxanHaqverdili it's a stream, not an iterator. Sometimes you have code that was written expecting to be `cout`ed (or `cin`ed) – Caleth Jun 10 '21 at 16:13
  • @Caleth `std::format` falls back to `operator<<`, right? I don't see how the same buffer cannot be used with `format_to`. – Aykhan Hagverdili Jun 10 '21 at 16:16
  • @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? – Nicol Bolas Jun 10 '21 at 16:20
  • @Nicol we have `format_to_n` for bounds checking. – Aykhan Hagverdili Jun 10 '21 at 16:23
  • 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. – Aykhan Hagverdili Jun 10 '21 at 16:24
  • @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. – Nicol Bolas Jun 10 '21 at 16:27
  • @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. – Aykhan Hagverdili Jun 10 '21 at 16:35
  • @AyxanHaqverdili `std::format` doesn't have an `operator<<` fallback. – T.C. Jun 10 '21 at 21:35
  • @T.C. [here](https://youtu.be/ptba_AqFYCM?t=2043) 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. – Aykhan Hagverdili Jun 10 '21 at 21:42
  • fmt does, but the std one doesn't (this sort of fallback is an ODR-violation magnet) – T.C. Jun 10 '21 at 21:49
  • @T.C. what do you mean by "ODR-violation management"? Would it be an ODR violation for `std::format` to fallback on `operator<<`? – Aykhan Hagverdili Jun 10 '21 at 22:07
  • 2
    @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. – Nicol Bolas Jun 10 '21 at 22:30
  • 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" – Lorah Attkins Jun 01 '23 at 12:54
  • @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. – Nicol Bolas Jun 01 '23 at 13:28
  • @NicolBolas There's cases where `stringstream` is [inadequate](https://social.msdn.microsoft.com/Forums/en-US/933f1985-82cd-48f1-a198-2277523c212a/stdstringstreamltchar8gt-does-not-work-properly-if-the-stream-size-is-more-than-4gb?forum=vclanguage) 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. – Lorah Attkins Jun 01 '23 at 14:59
  • @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. – Nicol Bolas Jun 01 '23 at 17:06
  • @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.](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0448r4.pdf). It's less misleading to call it a "departure from that design" since that is what the introduction of spanstream signifies. – Lorah Attkins Jun 01 '23 at 17:39