4

Apparently, C++20 has a new std::istream-related construct: std::istream_view. The cppreference page on it is a stub right now. So, what is a "view of an istream" and what can I use it for?


† - Ok, technically it redirects to a page about std::basic_istream_view and that one's a stub.

Barry
  • 286,269
  • 29
  • 621
  • 977
einpoklum
  • 118,144
  • 57
  • 340
  • 684

1 Answers1

5

An std::istream_view<T> is a range; and more specifically, a range formed as a view. This addition to the standard library is akin to what you might find under std::ranges::views - except that it's not a view of an arbitrary range, but of an std::istream.

So what "viewing" is applied to an std::istream? Recall an istream is a stream of characters, not of arbitrary T-type elements of your choice. The lazy application of parsing those characters into consecutive T's is the "viewing" of the the istream. That is, the k'th element of std::istream_view<T>(is) is what you'd get the k'th time running is >> t for t of type T.

You would use an std::istream_view (carefully) when you want to apply your code, which works with ranges, directly to input data - rather than first parsing your input into some data structure in a more "old-school" manner, then working on that structure as a range.

Other takes on what an std::istream_view is:

  • @Barry has described it as the equivalent of a coroutine which parses Ts from an istream; read this answer for details (note it's about the istream view in the ranges-v3, much of which became the standard ranges library).
  • @NicolBolas considers it to be the result of "wrapping std::istream_iterator<T> in a C++20 view interface".
einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 2
    So it's just an `istream_iterator` wrapped in a C++20 view interface. – Nicol Bolas Dec 11 '20 at 22:44
  • @NicolBolas: Is it really just the pair of `std::istream_iterator(my_istream)` and `std::istream_iterator()`? – einpoklum Dec 11 '20 at 22:47
  • I doubt its using exactly those types, since I'm not sure if they count as conceptualized iterators. But what you described is the basic idea. – Nicol Bolas Dec 11 '20 at 22:48
  • @Barry: I was mistakenly assumign that switching element type makes it a non-view. Edited. – einpoklum Dec 11 '20 at 22:57
  • @NicolBolas You can think of it as that, except more efficient. `istream_iterator` has to have a `T` member, which means copying that iterator has to copy the `T`. Here, `istream_view` is the one with the `T` member while `istream_view::iterator` just has an `istream_view*`, so the iterators are cheaper to copy. – Barry Dec 11 '20 at 22:59
  • We don't often copy iterators, though. – Asteroids With Wings Dec 12 '20 at 16:08
  • 1
    @AsteroidsWithWings so you take your iterators by `&`? Why? I find most (if not all) people copying iterators all over the place. Call a `all_of` that does some `find_if`ing and you are having N^2 number of copies. You don't use ``? All of these stuff copies iterators. – Fureeish Dec 12 '20 at 17:12
  • @Fureeish Did I say never? Did I say I pass iterators by address? No... Let's avoid strawman arguments. How often do you do `all_of` with `find_if` inside? Your typical use case is like `std::find(begin, end, val)` and that's a couple of copies. Not nothing, sure, but is this really a massive deal? – Asteroids With Wings Dec 12 '20 at 21:19
  • @AsteroidsWithWings Did **I** say never? What's left if you don't copy them when passing? Combining `all_of` with `find_if` is common enough for people I've worked with (size of the company varied) to mention it. "Couple of copies" per use case is enough to consider "not often copying iterators" a mistake. Not to mention all the generic code that works on iterators and delegates work to other parts where they get copied *again*. So yeah, it is kind of a massive deal to make iterators as small as possible, simply because it's an established C++ convention that iterators are cheap to copy. – Fureeish Dec 12 '20 at 21:32
  • @Fureeish And a `char` _is_ cheap to copy. Like, _very_. I'm hearing a lot of assertions that "this is bad", but no actual data or solid convincing arguments on _why_ this is bad. I'd wager it took you longer to write your last comment than you'd ever have saved on copying `char`s stored in `istream_iterator`s. – Asteroids With Wings Dec 12 '20 at 21:34
  • @AsteroidsWithWIngs the thing with abstracting away the concept of iterators is that *all* iterators to be cheap to copy. In that case, one should care about them meeting those requirements. `char` is *always* cheap to copy, so you don't have to argue about that. When you compare `char`s to `iterator`s you say that "`char`s are very cheap to copy". Great. If we rely on `char`s being cheap to copy, we can as well rely on all `iterator`s being cheap to copy. Being conditionally cheap to copy (whether an iterator holds `char` or `string`) would defeat a lof of freedom of optimisations. – Fureeish Dec 12 '20 at 21:45
  • @Fureeish More strawmen! Nobody's talking about some other kind of iterator. We're talking about istream iterators. That's it. End of story. So those are `char` or, maybe, `wchar_t` which can be four bytes. Hardly taxing for your computer. You are still not really providing any evidence of a real, practical problem here. The point is that this istream_view does _not_, as far as I can see, offer any substantial performance benefits, contrary to some claims above. If you disagree, feel free to provide some _practical_ evidence! – Asteroids With Wings Dec 12 '20 at 21:46
  • 1
    @AsteroidsWithWings ehh... I am providing a generic view on iterator usability... Not storing a variable inside an iterator is obviously better for space then actually storing it. – Fureeish Dec 12 '20 at 21:56
  • @Fureeish There's nothing "obvious" about that claim at all. Regardless, it seems you're talking about something unrelated to the topic of this Q&A, so let's move on. – Asteroids With Wings Dec 12 '20 at 22:01
  • @AsteroidsWithWings: Without taking sides here - don't istream iterators keep a `T` value, rather than a `char` or `wchar_t`? – einpoklum Dec 12 '20 at 23:05
  • @einpoklum Oh, well that's a good point - I guess I was thinking more of `istreambuf_iterator` then! – Asteroids With Wings Dec 12 '20 at 23:37
  • More to the point - is this discussion supposed to result in an edit or a recommendation of an edit? :-\ – einpoklum Dec 13 '20 at 21:39