Bug 96070 - std::views::* won't work with non-legacy iterators
Summary: std::views::* won't work with non-legacy iterators
Status: RESOLVED DUPLICATE of bug 95983
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 11.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2020-07-06 02:08 UTC by gcc-bugs
Modified: 2021-04-20 15:39 UTC (History)
2 users (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed:


Note You need to log in before you can comment on or make changes to this bug.
Description gcc-bugs 2020-07-06 02:08:09 UTC
Hi gcc-team,

not long ago a filed a bug-report[1] that `std::ranges::basic_istream_view::iterator` has no `std::iterator_traits` entry. 

> Your mistake is thinking that the iterators of views are like the iterators you're used to.

It seems that not only I had that problem, because this has some interesting consequences for the standard, for example the `std::ranges::filter_view::iterator` is described as [2]:

> 3 iterator​::​iterator_­category is defined as follows:
> (3.1) Let C denote the type iterator_­traits<iterator_­t<V>>​::​iterator_­category.
> (3.2) If C models derived_­from<bidirectional_­iterator_­tag>, then iterator_­category denotes bidirectional_­iterator_­tag.
> (3.3) Otherwise, if C models derived_­from<forward_­iterator_­tag>, then iterator_­category denotes forward_­iterator_­tag.
> (3.4) Otherwise, iterator_­category denotes C.

This assumes that `iterator_­traits<iterator_­t<V>>​::​iterator_­category` is defined which is not true for all iterators, like `std::ranges::basic_istream_view::iterator`.

A quick check with the gcc stdlib implementation:

#include <iostream>
#include <ranges>
#include <vector>

int main()
    // using input_view_t = std::vector<int> &; // works
    using input_view_t = std::ranges::basic_istream_view<char, char, std::char_traits<char>>; // does not work

    auto accept_all = [](auto &&){return true;};
    using filter_input_view_t = decltype(std::declval<input_view_t>() | std::views::filter(accept_all));
    using filter_iterator_t = std::ranges::iterator_t<filter_input_view_t>;


And yes it does not work.

Since I don't know of a generic way to conditionally include/exclude `using iterator_category = some_tag`, I think the easiest way would to allow `iterator_category = void`.

We would need to change the behaviour of `std::iterator_traits`. We should not only check whether all 4 members are available, but also that `iterator_category` is at least an input_iterator_tag or an output_iterator_tag. Or alternatively check that `iterator_category` is non-void.

I don't know how to create a LWG issue and if this problem was already reported, but I hope you can create one like in my last finding [3].

If this defect was not reported yet, it would be nice to at least link back to this issue and not just write "A user reported that this doesn't compile: ".

[1] - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94674
[2] - https://eel.is/c++draft/range.filter.iterator#3
[3] - https://cplusplus.github.io/LWG/issue3448
Comment 1 Jonathan Wakely 2020-07-06 10:50:04 UTC
(In reply to gcc-bugs from comment #0)
> I don't know how to create a LWG issue

Comment 2 Jonathan Wakely 2020-07-08 20:06:26 UTC
(In reply to gcc-bugs from comment #0)
> Hi gcc-team,
> not long ago a filed a bug-report[1] that
> `std::ranges::basic_istream_view::iterator` has no `std::iterator_traits`
> entry. 

Which is also the cause of PR 95983.
Comment 3 Patrick Palka 2021-04-20 15:38:00 UTC
This is also fixed by P2259R1, so let's mark this PR as a dup of PR95893.

*** This bug has been marked as a duplicate of bug 95893 ***
Comment 4 Patrick Palka 2021-04-20 15:39:12 UTC
Whoops, rather PR95983...

*** This bug has been marked as a duplicate of bug 95983 ***