范围适配器 counted ()
范围适配器 std::views::counted()
提供了从开始迭代器和计数创建视图的最灵活方法。
根据您传递的内容,它会为 start迭代器/指针的前 n 个元素创建一个简单视图。
程序员负责确保计数是有效的(传递一个过高的计数会导致未定义的行为)。
计数可能为0,这意味着范围为空。
count (beg,sz)
根据所调用的范围的特征产生不同的类型
- 如果传递的开始迭代器是
contiguous_iterator
(指存储在连续内存中的元素),则会产生std::span
。这适用于std::vector<>
、std::array<>
和原始数组的原始指针和迭代器。 - 如果传递的开始迭代器是一个随机访问迭代器(支持在元素之间来回跳转),则它将生成
std::ranges::subrange
。这适用于std::deque<>
的迭代器。 - 否则,它将生成
std:: counts
迭代器的std::ranges::subrange
,该迭代器具有default_sentinel
的伪哨点。这意味着迭代器在迭代时计数子范围。这适用于列表、关联容器和无序容器(哈希表)的迭代器。
例子:
std::vector<int> vec{1,2,3,4,5,6,7,8,9};
auto vec5 = std::ranges::find(vec,5);
auto v1 = std::views::counted(vec5, 3); //查看 VEC 中的元素 5 和 2 其他元素
//V1是std::span<int
std::deque<int> deq{1,2,3,4,5,6,7,8,9}; auto deq5 = std::ranges::find(deq,5);
auto v2 = std::views::counted(deq5, 3); // 查看deq中的元素5和另外2个元素
// V2是std::ranges::subrange<std::deque<int>::iterator
std::list<int> 1st{1,2,3,4,5,6,7,8,9}; auto 1st5 = std::ranges::find(1st,5);
auto v2 = std::views::counted(1st5, 3); // 查看元素 5 和 2 更多元素在 1st
// V3是std::ranges::subrange<std:: counting iterator<std::list<int>::iterator
// std::default_sentinel_t>
请注意,这段代码存在风险,因为如果集合中没有5且后面有两个元素,它会创建未定义的行为。
所以,如果你不确定情况是这样的话,你应该检查一下。
还要注意的是,如果你想要一个范围的前3个元素,使用take视图是一种更安全的获取结果的方式
std::vector<int> vec{1,2,3,4,5,6,7,8,9};
auto v1 = std::views::take(vec,3); //查看 VEC 中的前 3 个元素
take视图会检查是否有足够的元素,如果没有,则生成较少的元素。
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 N 天,点击查看活动详情”