在 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)
和 std::views::all(v) | std::views::drop(2)
。
那么,我的问题是:
什么是 std::views::all
在C++20中引入了什么?
But I cannot tell any difference between v | std::views::drop(2)
and std::views::all(v) | std::views::drop(2)
.
确实,两者之间没有区别——因为v | views::drop(2)
已经意味着views::all(v) | views::drop(2)
。
views::all
是范围的实现细节,以确保范围适配器始终适应 views(不是范围)。 views::all(v)
所做的只是确保结果是一个视图,也就是说(来自 [range.all]):
Given a subexpression E
, the expression views::all(E)
is expression-equivalent to:
decay-copy(E)
if the decayed type of E
models view
.
- Otherwise,
ref_view{E}
if that expression is well-formed.
- Otherwise,
subrange{E}
.
在您的例子中,v
是 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
。
#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)
。
那么,我的问题是:
什么是 std::views::all
在C++20中引入了什么?
But I cannot tell any difference between
v | std::views::drop(2)
andstd::views::all(v) | std::views::drop(2)
.
确实,两者之间没有区别——因为v | views::drop(2)
已经意味着views::all(v) | views::drop(2)
。
views::all
是范围的实现细节,以确保范围适配器始终适应 views(不是范围)。 views::all(v)
所做的只是确保结果是一个视图,也就是说(来自 [range.all]):
Given a subexpression
E
, the expressionviews::all(E)
is expression-equivalent to:
decay-copy(E)
if the decayed type ofE
modelsview
.- Otherwise,
ref_view{E}
if that expression is well-formed.- Otherwise,
subrange{E}
.
在您的例子中,v
是 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
。