But I cannot tell any difference between v | std::views::drop(2)
and std::views::all(v) | std::views::drop(2)
.
Indeed, there is no difference between the two - because v | views::drop(2)
already means views::all(v) | views::drop(2)
.
views::all
is an implementation detail of Ranges to ensure that range adaptors always adapt views (not ranges). All that views::all(v)
does is ensure that the result is a View, which is to say (from [range.all]):
Given a subexpression E
, the expression views::all(E)
is expression-equivalent to:
decay-copy(E)
if the decayed type of E
models view
.
- Otherwise,
ref_view{E}
if that expression is well-formed.
- Otherwise,
subrange{E}
.
In your case, v
is a vector<int>
, which does not model view
. But it is an lvalue, so ref_view{v}
would be well-formed, so that's what happens.
All the adaptors use views::all
internally. For instance, drop_view
has the following deduction guide:
template <class R>
drop_view(R&&, range_difference_t<R>) -> drop_view<views::all_t<R>>;
So if you wrote drop_view(v, 2)
(and you should never use meow_view
directly, always use views::meow
), that would itself invoke views::all
for you.