std::ranges::views::counted
std::ranges::views::counted
基本概念
1. 功能
- 创建子范围视图:根据给定的迭代器和元素数量,创建一个包含
N
个连续元素的视图。 - 惰性求值:不复制元素,直接引用原始数据。
- 兼容性:支持所有满足
std::input_iterator
的迭代器类型。
语法与参数
1. 语法
auto counted_view = std::ranges::views::counted(iterator, count);
iterator
:起始迭代器。count
:子范围包含的元素数量(必须非负)。
示例
示例 1:处理数组
#include <iostream>
#include <ranges>
int main()
{
int arr[] = {1, 2, 3, 4, 5};
// 从第2个元素开始,取3个元素
auto view = std::views::counted(arr + 1, 3);
for (int num : view)
{
std::cout << num << " "; // 输出:2 3 4
}
}
示例 2:处理容器
#include <iostream>
#include <ranges>
#include <vector>
int main()
{
std::vector<int> data = {10, 20, 30, 40, 50};
// 从第3个元素开始,取2个元素
auto it = data.begin() + 2;
auto view = std::views::counted(it, 2);
for (int num : view)
{
std::cout << num << " "; // 输出:30 40
}
}
示例 3:与其他视图适配器组合
#include <iostream>
#include <ranges>
#include <vector>
int main()
{
std::vector<int> data = {1, 2, 3, 4, 5};
// 取前3个元素,再过滤偶数
auto view = std::views::counted(data.begin(), 3)
| std::views::filter([](int x) { return x % 2 != 0; });
for (int num : view)
{
std::cout << num << " "; // 输出:1 3
}
}
示例 4:处理输入迭代器
#include <iostream>
#include <ranges>
#include <sstream>
#include <iterator>
int main()
{
std::istringstream iss("1 2 3 4 5");
auto input_it = std::istream_iterator<int>(iss);
// 从输入流迭代器开始,取3个元素
auto view = std::views::counted(input_it, 3);
for (int num : view)
{
std::cout << num << " "; // 输出:1 2 3
}
}
注意事项
-
迭代器有效性:
counted_view
是原始范围的视图,不拥有数据。确保底层数据在视图使用期间有效。- 若迭代器是悬空引用(如指向已销毁的容器),行为未定义。
-
数量限制:
count
必须是非负整数,否则行为未定义。- 若
count
超过实际剩余元素数量,视图会以实际剩余元素为界。
与 take_view
的区别
| 特性 | counted_view
| take_view
|
参数类型 | 迭代器 + 元素数量 范围 + 元素数量 | |
适用场景 | 已知起始迭代器但无完整范围时 直接操作现有范围时 | |
典型用例 | 处理迭代器来自非范围上下文(如指针) 从已有范围开头截取子范围 |
总结
- 核心用途:基于迭代器和数量快速创建子范围视图。
- 适用场景:
- 处理原始指针或迭代器(如 C 风格数组)。
- 与其他视图适配器组合使用。
- 需要精确控制起始位置和元素数量的场景。