The code snippet:
auto v = std::vector{1, 2, 3, 4, 5};
auto r = v |
std::views::transform([](int i) { return i - 42; });
static_assert(std::ranges::forward_range);
using I = std::ranges::iterator_t;
static_assert(std::forward_iterator);
// this fails
// static_assert(std::derived_from::iterator_category,
// std::forward_iterator_tag>);
// WTF?
static_assert(std::same_as::iterator_category,
std::input_iterator_tag>);
static_assert(std::same_as);
https://godbolt.org/z/WTdxvY51d
The doc says std::views::transform gives forward_range if the base range models it, bidirectional_range if the base is bidirectional, etc.
The curious thing I don't understand is that the resulting range satisfies forward_range concept, its iterator satisfies forward_iterator concept (which contains the requirement std::derived_from*ITER_CONCEPT*/, std::forward_iterator_tag>),
but the actual iterator category is std::input_iterator_tag.
Why the discrepancy?
The behavior is the same across major standard library implementations.