Namespaces
Variants

Ranges library (since C++20)

From cppreference.net
Ranges library
Range adaptors

范围库是对算法和迭代器库的扩展和泛化,通过使其可组合且更不易出错,从而增强其功能。

该库创建并操作范围 视图 ,这些轻量级对象间接表示可迭代序列( 范围 )。范围是在

  • [ begin , end ) – 迭代器对,例如通过容器隐式转换构成的区间。所有接受迭代器对的算法现在都有接受区间的重载版本(例如 ranges::sort
  • begin + [ 0 , size ) – 计数序列,例如由 views::counted 返回的区间
  • [ begin , predicate ) – 条件终止序列,例如由 views::take_while 返回的区间
  • [ begin , .. ) – 无界序列,例如由 views::iota 返回的区间

范围库包含 范围算法 (立即应用于范围)和 范围适配器 (延迟应用于视图)。适配器可组合成管道,使得其操作在迭代视图时执行。

定义于头文件 <ranges>
namespace std {

namespace views = ranges :: views ;

}
(C++20 起)

命名空间别名 std::views 作为 std::ranges::views 的简写形式提供。

定义于命名空间 std::ranges

目录

范围访问
定义于头文件 <ranges>
定义于头文件 <iterator>
返回指向范围起始的迭代器
(定制点对象)
返回指示范围结尾的哨位
(定制点对象)
返回指向只读范围起始的迭代器
(定制点对象)
返回指示只读范围结尾的哨位
(定制点对象)
返回指向范围的反向迭代器
(定制点对象)
返回指向范围的反向结尾迭代器
(定制点对象)
返回指向只读范围的反向迭代器
(定制点对象)
返回指向只读范围的反向结尾迭代器
(定制点对象)
返回等于范围给出的预留提示的整数
(定制点对象)
返回等于范围大小的整数
(定制点对象)
返回等于范围大小的有符号整数
(定制点对象)
检查范围是否为空
(定制点对象)
获取指向连续范围起始的指针
(定制点对象)
获取指向只读连续范围起始的指针
(定制点对象)
范围原语
定义于头文件 <ranges>
获取范围的迭代器和哨位类型
(别名模板)
获取范围的大小、差值和值类型
(别名模板)

范围工厂

定义于头文件 <ranges>
定义于命名空间 std::ranges
不含任何元素的空 view
(类模板) (变量模板)
包含单个指定值元素的 view
(类模板) (定制点对象)
通过重复递增初始值生成的序列构成的 view
(类模板) (定制点对象)
通过重复生成相同值构成的序列的 view
(类模板) (定制点对象)
通过对关联输入流连续应用 operator>> 所获元素构成的 view
(类模板) (定制点对象)

范围适配器

定义于头文件 <ranges>
定义于命名空间 std::ranges
用于定义范围适配器闭包对象的辅助基类模板
(类模板)
包含 range 所有元素的 view
(别名模板) (范围适配器对象)
某个其他 range 的元素的 view
(类模板)
对某个 range 具有唯一所有权的 view
(类模板)
将每个元素转换为右值的序列的 view
(类模板) (范围适配器对象)
由满足谓词的 range 元素组成的 view
(类模板) (范围适配器对象)
对每个元素应用转换函数的序列的 view
(类模板) (范围适配器对象)
由另一个 view 的前 N 个元素组成的 view
(类模板) (范围适配器对象)
由另一个 view 的初始元素组成的 view ,直到谓词返回 false 的第一个元素
(类模板) (范围适配器对象)
由跳过前 N 个元素的另一个 view 的元素组成的 view
(类模板) (范围适配器对象)
由跳过元素初始子序列(直到谓词返回 false 的第一个元素)的另一个 view 的元素组成的 view
(类模板) (范围适配器对象)
由展平 range s view 获得的序列组成的 view
(类模板) (范围适配器对象)
由展平范围视图并在元素之间插入分隔符获得的序列组成的 view
(类模板) (范围适配器对象)
通过使用分隔符分割另一个 view 获得的子范围的 view
(类模板) (范围适配器对象)
通过使用分隔符分割另一个 view 获得的子范围的 view
(类模板) (范围适配器对象)
由适配视图的串联组成的 view
(类模板) (定制点对象)
从迭代器和计数创建子范围
(定制点对象)
view 转换为 common_range
(类模板) (范围适配器对象)
以逆序迭代另一个双向视图元素的 view
(类模板) (范围适配器对象)
view 转换为 constant_range
<

范围生成器 (始于 C++23)

定义于头文件 <generator>
定义于命名空间 std
(C++23)
表示同步 协程 生成器的 view
(类模板)

辅助项

范围适配器对象

参见 RangeAdaptorObject (RAO)。

范围适配器闭包对象

参见 RangeAdaptorClosureObject (RACO)。

定制点对象

参见 定制点对象 (CPO)。

可赋值包装器

某些范围适配器会使用 copyable-box (C++23 前) movable-box (C++23 起) 来包装其元素或函数对象。该包装器在需要时通过赋予可赋值性来增强被包装对象的功能。

非传播缓存

某些范围适配器通过一个仅用于说明的类模板 non-propagating-cache 来定义,其行为几乎类似于 std:: optional < T > (具体差异请参阅相关描述)。

条件性 const 类型

template < bool Const, class T >
using /*maybe-const*/ = std:: conditional_t < Const, const T, T > ;
( 仅用于说明* )

别名模板 /*maybe-const*/ 是一种简写形式,用于根据条件向类型 T 选择性添加 const 限定符。

类整型辅助模板

template < /*is-integer-like*/ T >
using /*make-signed-like-t*/ < T > = /* see description */ ;
(1) ( 仅用于说明* )
template < /*is-integer-like*/ T >
using /*make-unsigned-like-t*/ < T > = /* see description */ ;
(2) ( 仅用于说明* )
template < /*is-integer-like*/ T >

/*make-unsigned-like-t*/ < T > /*to-unsigned-like*/ ( T t )
{
return static_cast < /*make-unsigned-like-t*/ < T >> ( t ) ;

}
(3) ( 仅用于说明* )
1) 对于 整数类型 T
  • T 为整数类型, /*make-signed-like-t*/ < T > std:: make_signed_t < T >
  • 否则, /*make-signed-like-t*/ < T > 为与 T 等宽的未指定对应有符号整数类型。
2) 对于整数类类型 T
  • T 为整数类型, /*make-unsigned-like-t*/ < T > std:: make_unsigned_t < T >
  • 否则, /*make-signed-like-t*/ < T > 为与 T 等宽的对应未指定无符号整数类类型。
3) t 显式转换为 /*make-unsigned-like-t*/ < T >

定制点对象辅助工具

template < ranges:: input_range R >

constexpr auto & /*可能常量范围*/ ( R & r ) noexcept
{
if constexpr ( ranges:: input_range < const R > )
return const_cast < const R & > ( r ) ;
else
return r ;

}
(1) ( 仅用于说明* )
template < class T >

constexpr auto /*作为常量指针*/ ( const T * p ) noexcept
{
return p ;

}
(2) ( 仅用于说明* )

某些范围访问定制点对象是根据这些仅用于说明的函数模板来指定的。

1) /*possibly-const-range*/ const R 满足 input_range 概念,则返回 r 的常量限定版本;否则直接返回 r 而不进行任何类型转换。
2) /*as-const-pointer*/ 返回指向常量类型对象的指针。

范围适配器辅助工具

template < class F, class Tuple >

constexpr auto /*tuple-transform*/ ( F && f, Tuple && tuple )
{
return std:: apply ( [ & ] < class ... Ts > ( Ts && ... args )
{
return std:: tuple < std:: invoke_result_t < F & , Ts > ... >
( std:: invoke ( f, std:: forward < Ts > ( args ) ) ... ) ;
} , std:: forward < Tuple > ( tuple ) ) ;

}
(1) ( 仅用于说明* )
template < class F, class Tuple >

constexpr void /*tuple-for-each*/ ( F && f, Tuple && tuple )
{
std:: apply ( [ & ] < class ... Ts > ( Ts && ... args )
{
( static_cast < void > ( std:: invoke ( f, std:: forward < Ts > ( args ) ) ) , ... ) ;
} , std:: forward < Tuple > ( tuple ) ) ;

}
(2) ( 仅用于说明* )
template < class T >

constexpr T & /*as-lvalue*/ ( T && t )
{
return static_cast < T & > ( t ) ;

}
(3) ( 仅用于说明* )

某些范围适配器是根据这些仅用于说明的函数模板来定义的。

1) /*tuple-transform*/ 返回通过将 f 应用于 tuple 的每个元素而构造的新元组。
2) /*tuple-for-each*/ tuple 中的每个元素应用 f 且不返回任何值。
3) /*as-lvalue*/ 将右值 t 作为左值转发。

辅助概念

以下仅用于说明的概念被用于若干类型,但它们并非标准库接口的组成部分。

template < class R >

concept /*简单视图*/ =
ranges:: view < R > && ranges:: range < const R > &&
std:: same_as < ranges:: iterator_t < R > , ranges:: iterator_t < const R >> &&

std:: same_as < ranges:: sentinel_t < R > , ranges:: sentinel_t < const R >> ;
(1) ( 仅用于说明* )
template < class I >

concept /*具有箭头操作符*/ =
ranges :: input_iterator < I > &&

( std:: is_pointer_v < I > || requires ( const I i ) { i. operator - > ( ) ; } ) ;
(2) ( 仅用于说明* )
template < class T, class U >

concept /*不同于*/ =

! std:: same_as < std:: remove_cvref_t < T > , std:: remove_cvref_t < U >> ;
(3) ( 仅用于说明* )
template < class R >

concept /*具有可移动引用类型的范围*/ =
ranges:: input_range < R > &&
std:: move_constructible < ranges:: range_reference_t < R >> &&

std:: move_constructible < ranges:: range_rvalue_reference_t < R >> ;
(4) ( 仅用于说明* )
template < bool C, class ... Views >

concept /*全随机访问*/ =
( ranges:: random_access_range

< std:: conditional_t < C, const Views, Views >> && ... ) ;
(5) ( 仅用于说明* )
template < bool C, class ... Views >

concept /*全双向*/ =
( ranges:: bidirectional_range

< std:: conditional_t < C, const Views, Views >> && ... ) ;
(6) ( 仅用于说明* )
template < bool C, class ... Views >

concept /*全前向*/ =
( ranges:: forward_range

< std:: conditional_t < C, const Views, Views >> && ... ) ;
(7) ( 仅用于说明* )

注释

特性测试 标准 特性
__cpp_lib_generator 202207L (C++23) std:: generator – 用于范围的同步协程生成器
__cpp_lib_ranges 201911L (C++20) 范围库和 约束算法
202106L (C++23)
(DR20)
可默认初始化 视图
202110L (C++23)
(DR20)
具有 所有权 视图
202202L (C++23) ranges:: range_adaptor_closure
202207L (C++23) 放宽 范围适配器 以允许仅移动类型
202211L (C++23) 移除 ranges:: begin 等中的"毒丸" (P2602) 重载
202302L (C++23) 放宽范围以允许特定投影
202406L (C++26)
(DR20)
从间接可调用概念中移除共同引用要求
__cpp_lib_ranges_as_const 202207L (C++23) std:: const_iterator , ranges:: as_const_view
__cpp_lib_ranges_as_rvalue 202207L (C++23) ranges:: as_rvalue_view
__cpp_lib_ranges_cache_latest 202411L (C++26) ranges :: cache_latest_view
__cpp_lib_ranges_cartesian_product 202207L (C++23) ranges:: cartesian_product_view
__cpp_lib_ranges_chunk 202202L (C++23) ranges:: chunk_view
__cpp_lib_ranges_chunk_by 202202L (C++23) ranges:: chunk_by_view
__cpp_lib_ranges_concat 202403L (C++26) ranges:: concat_view
__cpp_lib_ranges_enumerate 202302L (C++23) ranges :: enumerate_view
__cpp_lib_ranges_join_with 202202L (C++23) ranges:: join_with_view
__cpp_lib_ranges_repeat 202207L (C++23) ranges:: repeat_view
__cpp_lib_ranges_reserve_hint 202502L (C++26) ranges :: reserve_hint ranges :: approximately_sized_range
__cpp_lib_ranges_slide 202202L (C++23) ranges:: slide_view
__cpp_lib_ranges_stride 202207L (C++23) ranges:: stride_view
__cpp_lib_ranges_to_container 202202L (C++23) ranges:: to
__cpp_lib_ranges_to_input 202502L (C++26) ranges :: to_input_view
__cpp_lib_ranges_zip 202110L (C++23) ranges:: zip_view ,
ranges:: zip_transform_view ,
<a href="ranges/adjacent

示例

#include <iostream>
#include <ranges>
int main()
{
    auto const ints = {0, 1, 2, 3, 4, 5};
    auto even = [](int i) { return 0 == i % 2; };
    auto square = [](int i) { return i * i; };
    // 使用管道语法组合视图:
    for (int i : ints | std::views::filter(even) | std::views::transform(square))
        std::cout << i << ' ';
    std::cout << '\n';
    // 传统函数式组合语法:
    for (int i : std::views::transform(std::views::filter(ints, even), square))
        std::cout << i << ' ';
}

输出:

0 4 16
0 4 16

缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的C++标准。

缺陷报告 应用于 发布时的行为 正确行为
LWG 3509
( P2281R1 )
C++20 范围适配器对象如何绑定尾部参数不明确 通过值绑定
LWG 3948 C++23 possibly-const-range as-const-pointer
未声明为 noexcept
声明为 noexcept
LWG 4027 C++23 possibly-const-range 不会对已建模
constant_range 的范围添加常量限定
对此类范围
添加常量限定
LWG 4112 C++20 has-arrow 不要求 i 具有常量限定 要求具有

参见