https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96070
Bug ID: 96070 Summary: std::views::* won't work with non-legacy iterators Product: gcc Version: 11.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: gcc-bugs at marehr dot dialup.fu-berlin.de Target Milestone: --- 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: ```c++ #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>; } ``` https://godbolt.org/z/Uozktw 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