C++20 中引入的 std::views::all 是什么?

xml*_*lmx 4 c++ standards c++-standard-library c++20 std-ranges

#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
}
Run Code Online (Sandbox Code Playgroud)

成功编译g++11 -std=c++20。但我无法分辨v | std::views::drop(2)和之间的任何区别std::views::all(v) | std::views::drop(2)

所以,我的问题是:

C++20 中引入了什么std::views::all

Bar*_*rry 6

但我无法分辨v | std::views::drop(2)和之间的任何区别std::views::all(v) | std::views::drop(2)

确实,两者之间没有区别 - 因为v | views::drop(2)已经意味着views::all(v) | views::drop(2)

views::all是 Ranges 的实现细节,以确保范围适配器始终适应视图(而不是范围)。所有这一切views::all(v)确实是确保结果是一个视图,这是(自说[range.all] ):

给定一个子表达式E,该表达式views?::?all(E)是表达式等价于:

  • decay-copy(E)如果是腐烂型的E车型view
  • 否则,ref_­view{E}如果该表达式格式正确。
  • 否则,subrange{E}

在您的情况下,v是 a vector<int>,它不会对view. 但它是一个左值,所以ref_view{v}会是格式良好的,所以这就是会发生的事情。

所有适配器都在views::all内部使用。例如,drop_view有以下推导指南:

template <class R>
drop_view(R&&, range_difference_t<R>) -> drop_view<views::all_t<R>>;
Run Code Online (Sandbox Code Playgroud)

所以如果你写了drop_view(v, 2)(你永远不应该meow_view直接使用,总是使用views::meow),它本身会views::all为你调用。

  • 随着 C++23 `owning_view` 的引入,我认为这个答案可以更新。另外,我认为`views::all`在某些情况下应该更*专业化*,即当`E`是`string&amp;`时,`views::all(E)`应该是`string_view`,而当`E`是`string&amp;`时,`views::all(E)`应该是`string_view` `E` 是 `contigious_range&amp;`,`view::all(E)` 应该是 `span`,因为它们比 `ref_view` 对用户来说更方便。 (3认同)
  • @下划线_d。请参阅[*什么是视图?*](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2415r2.html) (3认同)