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