Namespaces
Variants

std::ranges:: subrange

From cppreference.net
Ranges library
Range adaptors
定义于头文件 <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*/ =

/* 见说明 */ ;
(2) ( 仅用于阐释* )
template < class From, class To >
concept /*convertible-to-non-slicing*/ = /* 见说明 */ ;
(3) ( 仅用于阐释* )
1) subrange 类模板将迭代器与哨位组合成单一的 view 。当最终模板参数为 subrange_kind​ :: ​sized 时(即满足 std:: sized_sentinel_for < S, I > 条件或通过构造函数显式传递size参数时),该模板实现 sized_range 概念。
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 [static] 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 的副本,其迭代器按给定距离推进
(公开成员函数)
继承自 std::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> 的公开成员函数)
返回派生视图中的第 n 个元素,仅在其满足 random_access_range 时提供
( std::ranges::view_interface<D> 的公开成员函数)

推导指引

非成员函数

std::ranges::subrange 获取迭代器或哨兵
(函数模板)

辅助类型

指定 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 可能拒绝限定转换 始终接受限定转换

参见

用于定义 view 的辅助类模板,采用 奇异递归模板模式
(类模板)

外部链接

在C++20中读写给定键对应的所有 std::multimap — Stack Overflow