c++standardsc++20stdstd-ranges

What is std::views::all introduced for in C++20?


#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?


Solution

  • 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.