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