8
#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
}

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

所以,我的问题是:

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

4

1 回答 1

10

但我无法区分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>>;

因此,如果您编写drop_view(v, 2)(并且您永远不应该meow_view直接使用,始终使用views::meow),那它本身就会views::all为您调用。

于 2021-04-30T14:10:58.830 回答