#include <vector>
#include <ranges>
int main()
{
auto v = std::vector{1, 2, 3, 4};
v | std::views::drop(2); // ok
std::views::all(v) | std::views::drop(2); // also ok
}
Successfully compiled with g++11 -std=c++20
. But I cannot tell any difference between v | std::views::drop(2)
and std::views::all(v) | std::views::drop(2)
.
So, my question is:
What is std::views::all
introduced for in C++20?
But I cannot tell any difference between
v | std::views::drop(2)
andstd::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 expressionviews::all(E)
is expression-equivalent to:
decay-copy(E)
if the decayed type ofE
modelsview
.- 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.