std::ranges::subrange
来自 zh.cppreference.net
| 定义于头文件 <ranges>
|
||
template<
std::input_or_output_iterator I,
std::sentinel_for<I> S = I,
ranges::subrange_kind K = std::sized_sentinel_for<S, I> ?
ranges::subrange_kind::sized :
ranges::subrange_kind::unsized >
requires (K == ranges::subrange_kind::sized || !std::sized_sentinel_for<S, I>)
class subrange
: public ranges::view_interface<subrange<I, S, K>>
|
(1) | (C++20 起) |
| 辅助概念 |
||
template<class From, class To>
concept /*uses-nonqualification-pointer-conversion*/ =
/* see description */;
|
(2) | (仅用于阐述*) |
template<class From, class To>
concept /*convertible-to-non-slicing*/ = /* see description */;
|
(3) | (仅用于阐述*) |
1) 类模板
subrange 将迭代器和哨位组合成单个 view。它符合 sized_range 当且仅当最后一个模板参数是 subrange_kind::sized 时(当 std::sized_sentinel_for<S, I> 满足,或 size 作为构造函数参数显式传递时发生)。2) 确定
From 是否可以在不发生To资质转换的情况下转换为 。等价于:
template<class From, class To>
concept /*uses-nonqualification-pointer-conversion*/ =
std::is_pointer_v<From> && std::is_pointer_v<To> &&
!std::convertible_to<std::remove_pointer_t<From>(*)[],
std::remove_pointer_t<To>(*)[]>;
3) 确定
From 是否可以在不发生派生到基类转换的情况下转换为 To:
template<class From, class To>
concept /*convertible-to-non-slicing*/ =
std::convertible_to<From, To> &&
!/*uses-nonqualification-pointer-conversion*/
<std::decay_t<From>, std::decay_t<To>>;
数据成员
| 成员 | 描述 |
constexpr bool StoreSize [静态]
|
K == ranges::subrange_kind::sized && !std::sized_sentinel_for<S, I>(仅为说明的静态成员常量*) |
I begin_
|
指向子范围起始的迭代器 (仅为说明的成员对象*) |
S end_
|
表示子范围末尾的哨位 (仅为说明的成员对象*) |
make-unsigned-like-t <std::iter_difference_t<I>> size_ (仅在 StoreSize 为 true 时存在)
|
子范围的大小 (仅为说明的成员对象*) |
成员函数
创建新的
subrange
(公开成员函数) |
|
将
subrange
转换为
pair-like
类型
(公开成员函数) |
|
观察器 |
|
|
获取迭代器
(公开成员函数) |
|
|
获取哨兵
(公开成员函数) |
|
检查
subrange
是否为空
(公开成员函数) |
|
获取
subrange
的大小
(公开成员函数) |
|
迭代器操作 |
|
|
按给定距离推进迭代器
(公开成员函数) |
|
获取
subrange
的副本,其迭代器按给定距离递减
(公开成员函数) |
|
获取
subrange
的副本,其迭代器按给定距离推进
(公开成员函数) |
|
继承自 ranges::view_interface | |
(C++23) |
返回指向范围起始的常量迭代器 ( std::ranges::view_interface<D> 的公开成员函数)
|
(C++23) |
返回范围常量迭代器的哨位 ( std::ranges::view_interface<D> 的公开成员函数)
|
| 返回所派生视图是否非空,仅在 ranges::empty 可应用于该视图时提供 ( std::ranges::view_interface<D> 的公开成员函数)
| |
| 获取派生视图数据的地址,仅在其迭代器类型满足 contiguous_iterator 时提供 std::ranges::view_interface<D>(公开成员函数)
| |
| 返回派生视图中的首个元素,在其满足 forward_range 时提供 std::ranges::view_interface<D>(公开成员函数)
| |
| 返回派生视图中的最后一个元素,仅在其满足 bidirectional_range 和 common_range 时提供 std::ranges::view_interface<D>(公开成员函数)
| |
返回派生视图中的第 nth 个元素,仅在其满足 random_access_range 时提供 std::ranges::view_interface<D>(公开成员函数)
| |
推导指引
非成员函数
|
(C++20)
|
从
std::ranges::subrange
获取迭代器或哨兵
(函数模板) |
辅助类型
|
(C++20)
|
指定
std::ranges::subrange
是否建模
std::ranges::sized_range
(枚举) |
|
获取
std::ranges::subrange
的大小
(类模板特化) |
|
|
获取
std::ranges::subrange
的迭代器或哨兵类型
(类模板特化) |
辅助模板
|
template
<
class
I,
class
S,
ranges::
subrange_kind
K
>
constexpr bool ranges:: enable_borrowed_range < ranges :: subrange < I, S, K >> = true ; |
(C++20 起) | |
此
ranges::
enable_borrowed_range
的特化使
subrange
满足
borrowed_range
的要求。
示例
运行此代码
#include <map> #include <print> #include <ranges> void make_uppercase(char& v) { v += 'A' - 'a'; } void uppercase_transform(std::multimap<int, char>& m, int k) { auto [first, last] = m.equal_range(k); for (auto& [_, v] : std::ranges::subrange(first, last)) make_uppercase(v); } int main() { std::multimap<int, char> mm{{4, 'a'}, {3, '-'}, {4, 'b'}, {5, '-'}, {4, 'c'}}; std::println("Before: {}", mm); uppercase_transform(mm, 4); std::println("After: {}", mm); }
输出:
Before: {3: '-', 4: 'a', 4: 'b', 4: 'c', 5: '-'}
After: {3: '-', 4: 'A', 4: 'B', 4: 'C', 5: '-'}
缺陷报告
下列行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。
| DR | 适用范围 | 发布时的行为 | 正确行为 |
|---|---|---|---|
| LWG 3470 | C++20 |
convertible-to-non-slicing
可能拒绝限定转换
|
始终接受限定转换 |
参见
|
(C++20)
|
用于定义
view
的辅助类模板,采用
奇异递归模板模式
(类模板) |
外部链接
在C++20中读写给定键对应的所有
std::multimap
值
— Stack Overflow
|