繁体   English   中英

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

[英]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
}

使用g++11 -std=c++20成功编译。 但我无法区分v | std::views::drop(2) v | std::views::drop(2)std::views::all(v) | std::views::drop(2) std::views::all(v) | std::views::drop(2)

所以,我的问题是:

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

但我无法区分v | std::views::drop(2) v | std::views::drop(2)std::views::all(v) | std::views::drop(2) std::views::all(v) | std::views::drop(2)

确实,两者没有区别——因为v | views::drop(2) v | views::drop(2)已经意味着views::all(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)模型的view E
  • 否则,如果该表达式格式正确, ref_view{E}
  • 否则, subrange{E}

在您的情况下, v是一个vector<int> ,它不是 model 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

您可能希望您的界面返回一个范围而不是底层容器。 在下面的示例中, container_api公开了不属于视图的成员方法(即 std::vector)(例如 rbegin()、capacity()、max_size())。 range_api公开了operator bool ,它不是向量的一部分。

另一个重要区别是 range_api 的返回类型是range_api而不是引用。 这可以防止用户在实际接口返回对容器的引用时认为他们正在获取范围的无意复制。

class Foo {
public:
     Foo() { ... }
     const auto& container_api() const { return m_vec; }
     auto range_api() const { return std::views::all(m_vec); }
private:
     std::vector<int> m_vec;
};

void some_fn(const Foo& foo)
{
   auto rng = foo.container_api();   // unwanted copy!
   ...
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM