在https://en.cppreference.com/w/cpp/ranges上,std::views::count列在范围适配器部分中。但是,它未标记为范围适配器对象。
我猜这就是为什么我不能使用管道操作符来编写的原因:
std::vector<size_t> vec = {1, 2, 3, 4, 5};
auto view = vec | std::ranges::counted(... ; // does not compile
我的问题是:
- 什么是**std::ranges::count?**为什么它列在range adapter部分?
- 使用案例是什么?使用take和drop有什么优势?
3条答案
按热度按时间yhqotfr81#
Cppreference遵循C++20标准的组织结构,它把
views::counted
放到the "Range Adaptors" section中,尽管标准说:可以链接这些适配器以创建范围变换的管道,这些管道在迭代结果视图时缓慢求值。
views::counted
的 behavior 并非如此。实际上,该节中的大多数其他元素都说它们的定制点“表示一个范围适配器对象”(描述管道功能),但views::counted
does not除外。不清楚为什么要把它放在那一节,但它本身就是一个有用的类型。它实际上只是一种表达
subrange(it, it + n)
的有效方式。它的有效性在于它实际上并不以n
递增迭代器。与
take_view
相比,它的优势在于take_view
对一个范围进行操作,而counted
所需要的只是一个迭代器。take_view
将为您提供 * 最多 *n
个对象,但如果范围小于此值,(如标记所定义),它不会尝试迭代超出范围的结尾。hpcdzsge2#
根据the docs
计数视图提供了对于某个迭代器i和非负整数n的计数范围[i,n)的元素的视图。
计数范围[i,n)是从i所指向的元素开始直到但不包括++i的n次应用的结果所指向的元素(如果有的话)的n个元素。
所以本质上,它返回一个切片,给定一个起始迭代器和在该迭代器之后要包含的一些元素。
输出量
比较您列出的特定函数,以下是它们的摘要:
std::ranges::views::take
:由另一个视图的前N个元素(最多)组成的视图std::ranges::views::drop
:由另一个视图的元素组成的视图,跳过(最多)前N个元素std::ranges::views::counted
:从迭代器和计数创建一个子范围,始终正好包含N个元素hmae6n7t3#
views::counted
类似于views::take
,但是前者接受迭代器而不是范围。views::counted
相对于views::take
的一个优点是,它允许我们在已知大小的情况下构建一个 sized 输入/输出范围:与
views::take
不同,由于我们省略了sentinel信息,我们必须确保迭代器在n
次递增后仍然有效,而前者保证总是返回有效的范围。