Ranges library (since C++20)
范围库是对算法和迭代器库的扩展和泛化,通过使其可组合且更不易出错,从而增强其功能。
该库创建并操作范围 视图 ,这些轻量级对象间接表示可迭代序列( 范围 )。范围是在
- 
        
         [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>
           
           | ||
| 
           
            
             
              (C++20)
             
            
           
           | 返回指向范围起始的迭代器 (定制点对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 返回指示范围结尾的哨位 (定制点对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 返回指向只读范围起始的迭代器 (定制点对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 返回指示只读范围结尾的哨位 (定制点对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 返回指向范围的反向迭代器 (定制点对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 返回指向范围的反向结尾迭代器 (定制点对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 返回指向只读范围的反向迭代器 (定制点对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 返回指向只读范围的反向结尾迭代器 (定制点对象) | |
| 
           
            
             
              (C++26)
             
            
           
           | 返回等于范围给出的预留提示的整数 (定制点对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 返回等于范围大小的整数 (定制点对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 返回等于范围大小的有符号整数 (定制点对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 检查范围是否为空 (定制点对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 获取指向连续范围起始的指针 (定制点对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 获取指向只读连续范围起始的指针 (定制点对象) | |
| 范围原语 | ||
| 
          定义于头文件
           
           
            <ranges>
           
           | ||
| 
           
            
             
              (C++20)
             
            
            
             
              (C++23)
             
            
            
             
              (C++20)
             
            
            
             
              (C++23)
             
            
           
           | 获取范围的迭代器和哨位类型 (别名模板) | |
| 
           
            
             
              (C++20)
             
            
            
             
              (C++20)
             
            
            
             
              (C++20)
             
            
           
           | 获取范围的大小、差值和值类型 (别名模板) | |
范围工厂
| 
          定义于头文件
           
           
            <ranges>
           
           | |
| 
          定义于命名空间
           
           std::ranges
           | |
| 
           
            
             
              (C++20)
             
            
           
           | 不含任何元素的空 
           view
          (类模板) (变量模板) | 
| 包含单个指定值元素的 
           view
          (类模板) (定制点对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 通过重复递增初始值生成的序列构成的 
           view
          (类模板) (定制点对象) | 
| 通过重复生成相同值构成的序列的 
           view
          (类模板) (定制点对象) | |
| 通过对关联输入流连续应用 
          operator>>
         所获元素构成的
           view
          (类模板) (定制点对象) | |
范围适配器
| 
          定义于头文件
           
           
            <ranges>
           
           | |
| 
          定义于命名空间
           
           std::ranges
           | |
| 
           
            
             
              (C++23)
             
            
           
           | 用于定义范围适配器闭包对象的辅助基类模板 (类模板) | 
| 
           
            
             
              (C++20)
             
            
           
           | 包含 
           range
          所有元素的
           view
          (别名模板) (范围适配器对象) | 
| 
           
            
             
              (C++20)
             
            
           
           | 某个其他 
           range
          的元素的
           view
          (类模板) | 
| 
           
            
             
              (C++20)
             
            
           
           | 对某个 
           range
          具有唯一所有权的
           view
          (类模板) | 
| 将每个元素转换为右值的序列的 
           view
          (类模板) (范围适配器对象) | |
| 由满足谓词的 
           range
          元素组成的
           view
          (类模板) (范围适配器对象) | |
| 对每个元素应用转换函数的序列的 
           view
          (类模板) (范围适配器对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 由另一个 
           view
          的前 N 个元素组成的
           view
          (类模板) (范围适配器对象) | 
| 由另一个 
           view
          的初始元素组成的
           view
          ,直到谓词返回
         
          
           
            false
           
          
         
         的第一个元素(类模板) (范围适配器对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 由跳过前 N 个元素的另一个 
           view
          的元素组成的
           view
          (类模板) (范围适配器对象) | 
| 由跳过元素初始子序列(直到谓词返回
         
          
           
            false
           
          
         
         的第一个元素)的另一个 
           view
          的元素组成的
           view
          (类模板) (范围适配器对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 由展平 
           range
          s
         
         的
           view
          获得的序列组成的
           view
          (类模板) (范围适配器对象) | 
| 由展平范围视图并在元素之间插入分隔符获得的序列组成的 
           view
          (类模板) (范围适配器对象) | |
| 通过使用分隔符分割另一个 
           view
          获得的子范围的
           view
          (类模板) (范围适配器对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 通过使用分隔符分割另一个 
           view
          获得的子范围的
           view
          (类模板) (范围适配器对象) | 
| 由适配视图的串联组成的 
           view
          (类模板) (定制点对象) | |
| 
           
            
             
              (C++20)
             
            
           
           | 从迭代器和计数创建子范围 (定制点对象) | 
| 将 
           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
             
              )
             
              | (3) | ( 仅用于说明* ) | 
        T
       
       :
       - 
         若
         T为整数类型, /*make-signed-like-t*/ < T > 即 std:: make_signed_t < T > 。
- 
         否则,
         
          
           /*make-signed-like-t*/
          
          
           <
          
          T
          
           >
          
         
         为与
         T等宽的未指定对应有符号整数类型。
        T
       
       :
       - 
         若
         T为整数类型, /*make-unsigned-like-t*/ < T > 即 std:: make_unsigned_t < T > 。
- 
         否则,
         
          
           /*make-signed-like-t*/
          
          
           <
          
          T
          
           >
          
         
         为与
         T等宽的对应未指定无符号整数类类型。
定制点对象辅助工具
| 
           
           
           
            
             template
            
            
             <
            
            
             
              ranges::
              
               input_range
              
             
            
            R
            
             >
            
             
             
              constexpr
             
             
              auto
             
             
              &
             
             
              /*可能常量范围*/
             
             
              (
             
             R
             
              &
             
             r
             
              )
             
             
              noexcept
             
              | (1) | ( 仅用于说明* ) | 
| 
           
           
           
            
             template
            
            
             <
            
            
             class
            
            T
            
             >
            
             
             
              constexpr
             
             
              auto
             
             
              /*作为常量指针*/
             
             
              (
             
             
              const
             
             T
             
              *
             
             p
             
              )
             
             
              noexcept
             
              | (2) | ( 仅用于说明* ) | 
某些范围访问定制点对象是根据这些仅用于说明的函数模板来指定的。
范围适配器辅助工具
| 
           
           
           
            
             template
            
            
             <
            
            
             class
            
            F,
            
             class
            
            Tuple
            
             >
            
             
             
              constexpr
             
             
              auto
             
             
              /*tuple-transform*/
             
             
              (
             
             F
             
              &&
             
             f, Tuple
             
              &&
             
             tuple
             
              )
             
              | (1) | ( 仅用于说明* ) | 
| 
           
           
           
            
             template
            
            
             <
            
            
             class
            
            F,
            
             class
            
            Tuple
            
             >
            
             
             
              constexpr
             
             
              void
             
             
              /*tuple-for-each*/
             
             
              (
             
             F
             
              &&
             
             f, Tuple
             
              &&
             
             tuple
             
              )
             
              | (2) | ( 仅用于说明* ) | 
| 
           
           
           
            
             template
            
            
             <
            
            
             class
            
            T
            
             >
            
             
             
              constexpr
             
             T
             
              &
             
             
              /*as-lvalue*/
             
             
              (
             
             T
             
              &&
             
             t
             
              )
             
              | (3) | ( 仅用于说明* ) | 
某些范围适配器是根据这些仅用于说明的函数模板来定义的。
辅助概念
以下仅用于说明的概念被用于若干类型,但它们并非标准库接口的组成部分。
| 
           
           
           
            
             template
            
            
             <
            
            
             class
            
            R
            
             >
            
             
             concept
             
              /*简单视图*/
             
             
              =
             
              | (1) | ( 仅用于说明* ) | 
| 
           
           
           
            
             template
            
            
             <
            
            
             class
            
            I
            
             >
            
             
             concept
             
              /*具有箭头操作符*/
             
             
              =
             
              | (2) | ( 仅用于说明* ) | 
| 
           
           
           
            
             template
            
            
             <
            
            
             class
            
            T,
            
             class
            
            U
            
             >
            
             
             concept
             
              /*不同于*/
             
             
              =
             
              | (3) | ( 仅用于说明* ) | 
| 
           
           
           
            
             template
            
            
             <
            
            
             class
            
            R
            
             >
            
             
             concept
             
              /*具有可移动引用类型的范围*/
             
             
              =
             
              | (4) | ( 仅用于说明* ) | 
| 
           
           
           
            
             template
            
            
             <
            
            
             bool
            
            C,
            
             class
            
            ...
            
             Views
            
            
             >
            
             
             concept
             
              /*全随机访问*/
             
             
              =
             
              | (5) | ( 仅用于说明* ) | 
| 
           
           
           
            
             template
            
            
             <
            
            
             bool
            
            C,
            
             class
            
            ...
            
             Views
            
            
             >
            
             
             concept
             
              /*全双向*/
             
             
              =
             
              | (6) | ( 仅用于说明* ) | 
| 
           
           
           
            
             template
            
            
             <
            
            
             bool
            
            C,
            
             class
            
            ...
            
             Views
            
            
             >
            
             
             concept
             
              /*全前向*/
             
             
              =
             
              | (7) | ( 仅用于说明* ) | 
注释
示例
#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
          
         
         具有常量限定 | 要求具有 |