Since basic_istream_view::iterator is neither a cpp17 iterator (because it's move-only) nor does it define all four of the types {difference_type, value_type, reference, iterator_category}, then by the rule in [iterator.traits], its iterator_traits has no members.
More concretely this means that it can't e.g. be composed with a views::transform or a views::filter because they look at the iterator_traits of the underlying view. This seems to be a defect in the current spec. libstdc++-v3/ChangeLog: * include/std/ranges (ranges::basic_istream_view::iterator::reference): Define it so that this iterator's iterator_traits is populated. * testsuite/std/ranges/istream_view.cc: Augment test. --- libstdc++-v3/include/std/ranges | 1 + libstdc++-v3/testsuite/std/ranges/istream_view.cc | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 891ecf75eff..6e982d6ded3 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -996,6 +996,7 @@ namespace views using iterator_category = input_iterator_tag; using difference_type = ptrdiff_t; using value_type = _Val; + using reference = _Val&; _Iterator() = default; diff --git a/libstdc++-v3/testsuite/std/ranges/istream_view.cc b/libstdc++-v3/testsuite/std/ranges/istream_view.cc index 1729459bce3..7feb3ff4b0a 100644 --- a/libstdc++-v3/testsuite/std/ranges/istream_view.cc +++ b/libstdc++-v3/testsuite/std/ranges/istream_view.cc @@ -68,10 +68,21 @@ test03() VERIFY( ranges::equal(v, (int[]){0,1,2,3,4}) ); } +void +test04() +{ + std::string s = "0123456789"; + auto ss = std::istringstream{s}; + static_assert(ranges::input_range<decltype(ranges::istream_view<X>(ss))>); + auto v = ranges::istream_view<X>(ss) | views::transform(&X::c); + VERIFY( ranges::equal(v, s) ); +} + int main() { test01(); test02(); test03(); + test04(); } -- 2.25.0.191.gde93cc14ab