Hi gcc-team, I'm not sure if I should have named the issue `std::iterator_traits is missing default values for an iterator` (https://eel.is/c++draft/iterator.traits#3.2). Maybe I misunderstood this, but I thought that I can query every iterator for it's traits. The following code does not work: ```c++ #include <ranges> #include <istream> #include <string_view> int main() { // std::string_view view; // does work auto && view = std::ranges::basic_istream_view<int, char, std::char_traits<char>>{}; // does not work // auto && view = std::ranges::take_view<std::string_view>{}; // does work using iterator_t = std::ranges::iterator_t<decltype(view)>; using iter_value1_t = std::iter_value_t<iterator_t>; using iter_value2_t = typename std::iterator_traits<iterator_t>::value_type; static_assert(std::same_as<iter_value1_t, iter_value2_t>); return 0; } ``` with `g++-10 -std=c++2a` https://godbolt.org/z/QAfdml
This is a known defect in the C++20 draft: https://cplusplus.github.io/LWG/issue3394
The current disposition of the Library Working Group is to leave it that way, because it doesn't meet the traditional iterator requirements, so it's expected that iterator_traits is empty for it. As you already know, you can use range_value_t<decltype(view)> to get the value type instead, and range_difference_t for the difference type, and use the concepts std::input_iterator, std::forward_iterator etc. to determine which concepts it satisfies. Code written to work with ranges should rely on those interfaces, not iterator_traits, which is for traditional iterator types.
Thank you for pointing me to this. I find this highly unexpected. There was made a change to `std::type_traits` in C++20 that sets default values, but it does not apply to all iterators? My use case was slightly different, I wanted to extract the `pointer` member type and there is no equivalent like `std::ranges::range_pointer_t` for that. This makes it particularly cumbersome to "forward" properties of an underlying iterator which is used when wrapping it in a new iterator.
That iterator doesn't have a pointer type, because in the new Ranges world that type is not useful. It is no longer required for iterators to have operator-> so what does the 'pointer' type even mean?
Your mistake is thinking that the iterators of views are like the iterators you're used to. They're not. They have different properties (e.g. they might not be copyable, they might not have operator->, they might not define iterator_category) and std::iterator_traits is for use with the old kind of iterators, not the new ones.