名稱空間
變體
操作

範圍庫 (C++20 起)

來自 cppreference.com
< cpp
 
 
範圍庫 (Ranges library)
範圍介面卡 (Range adaptors)
(C++23)(C++23)
(C++23)
(C++23)(C++23)
(C++23)(C++23)
(C++23)(C++23)
(C++23)(C++23)

 

範圍庫是演算法和迭代器庫的擴充套件和泛化,透過使其可組合且不易出錯,從而使其功能更強大。

該庫建立和操作範圍 _檢視_,它們是間接表示可迭代序列(_範圍_)的輕量級物件。範圍是基於以下概念的抽象:

  • [beginend) – 迭代器對,例如透過從容器隱式轉換建立的範圍。所有接受迭代器對的演算法現在都具有接受範圍的過載(例如 ranges::sort
  • begin + [0size) – 計數序列,例如 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++20)
返回等於範圍大小的整數
(定製點物件)[編輯]
(C++20)
返回等於範圍大小的有符號整數
(定製點物件)[編輯]
(C++20)
檢查範圍是否為空
(定製點物件)[編輯]
(C++20)
獲取指向連續範圍開頭的指標
(定製點物件)[編輯]
(C++20)
獲取指向只讀連續範圍開頭的指標
(定製點物件)[編輯]
範圍原語 (Range primitives)
定義於標頭檔案 <ranges>
獲取範圍的迭代器和哨兵型別
(別名模板)[編輯]
獲取範圍的大小、差值和值型別
(別名模板)[編輯]
獲取範圍的引用型別
(別名模板)[編輯]
懸空迭代器處理 (Dangling iterator handling)
定義於標頭檔案 <ranges>
一個佔位符型別,指示迭代器或 subrange 不應返回,因為它會懸空
(類) [編輯]
獲取 borrowed_range 的迭代器型別或 subrange 型別
(別名模板)[編輯]
其他實用工具
定義於標頭檔案 <ranges>
將範圍標記為序列而不是單個值
(類模板) [編輯]
範圍概念 (Range concepts)
定義於標頭檔案 <ranges>
(C++20)
指定型別為範圍,即它提供 begin 迭代器和 end 哨兵
(概念) [編輯]
指定型別為 range,並且從其表示式獲得的迭代器可以安全返回而不會有懸空的危險
(概念) [編輯]
指定範圍可以在常數時間內估算其大小
(概念) [編輯]
指定範圍在常數時間內知道其大小
(概念) [編輯]
(C++20)
指定範圍是檢視,即它具有常數時間複製/移動/賦值
(概念) [編輯]
指定其迭代器型別滿足 input_iterator 的範圍
(概念) [編輯]
指定其迭代器型別滿足 output_iterator 的範圍
(概念) [編輯]
指定其迭代器型別滿足 forward_iterator 的範圍
(概念) [編輯]
指定其迭代器型別滿足 bidirectional_iterator 的範圍
(概念) [編輯]
指定其迭代器型別滿足 random_access_iterator 的範圍
(概念) [編輯]
指定其迭代器型別滿足 contiguous_iterator 的範圍
(概念) [編輯]
指定範圍具有相同的迭代器和哨兵型別
(概念) [編輯]
指定 range 安全轉換為 view 的要求
(概念) [編輯]
指定範圍具有隻讀元素
(概念) [編輯]
範圍轉換 (Range conversions)
定義於標頭檔案 <ranges>
(C++23)
從輸入範圍構造新的非檢視物件
(函式模板) [編輯]
檢視
定義於標頭檔案 <ranges>
用於使用奇異遞迴模板模式定義view的輔助類模板
(類模板) [編輯]
將迭代器-哨兵對組合成view
(類模板) [編輯]

[編輯] 範圍工廠

定義於標頭檔案 <ranges>
定義於名稱空間std::ranges
一個不含元素的空 view
(類模板) (變數模板)[編輯]
一個包含單個指定值的 view
(類模板) (定製點物件)[編輯]
由重複遞增初始值生成的序列組成的 view
(類模板) (定製點物件)[編輯]
一個由重複生成相同值組成的view
(類模板) (定製點物件)[編輯]
一個view,由在相關輸入流上連續應用 operator>> 獲得的元素組成
(類模板) (定製點物件)[編輯]

[編輯] 範圍介面卡

定義於標頭檔案 <ranges>
定義於名稱空間std::ranges
用於定義範圍介面卡閉包物件的輔助基類模板
(類模板) [編輯]
包含range所有元素的view
(別名模板) (範圍介面卡物件)[編輯]
其他range元素的view
(類模板) [編輯]
一個具有對某些range的唯一所有權的view
(類模板) [編輯]
序列的 view,將每個元素轉換為右值
(類模板) (範圍介面卡物件)[編輯]
一個 view,由滿足謂詞的 range 的元素組成
(類模板) (範圍介面卡物件)[編輯]
一個將轉換函式應用於每個元素的序列 view
(類模板) (範圍介面卡物件)[編輯]
由另一個view的前N個元素組成的view
(類模板) (範圍介面卡物件)[編輯]
一個view,由另一個view的初始元素組成,直到第一個謂詞返回false的元素
(類模板) (範圍介面卡物件)[編輯]
由另一個view的元素組成的view,跳過前N個元素
(類模板) (範圍介面卡物件)[編輯]
一個view,由另一個view的元素組成,跳過初始子序列元素,直到第一個謂詞返回false的元素
(類模板) (範圍介面卡物件)[編輯]
一個view,由展平rangesview獲得的序列組成
(類模板) (範圍介面卡物件)[編輯]
一個 view,由扁平化範圍檢視獲得的序列組成,元素之間帶有分隔符
(類模板) (範圍介面卡物件)[編輯]
一個 view,包含透過分隔符拆分另一個 view 獲得的子範圍
(類模板) (範圍介面卡物件)[編輯]
一個 view,包含透過分隔符拆分另一個 view 獲得的子範圍
(類模板) (範圍介面卡物件)[編輯]
一個 view,由連線的介面卡檢視組成
(類模板) (定製點物件)[編輯]
(C++20)
從迭代器和計數建立子範圍
(定製點物件)[編輯]
view 轉換為 common_range
(類模板) (範圍介面卡物件)[編輯]
一個view,它以反向順序迭代另一個雙向檢視的元素
(類模板) (範圍介面卡物件)[編輯]
view 轉換為 constant_range
(類模板) (範圍介面卡物件)[編輯]
接受一個由_tuple-like_值和數字N組成的view,並生成一個由每個元組的Nth元素組成的view
(類模板) (範圍介面卡物件)[編輯]
接受一個由類似對的值組成的view,並生成一個由每對的第一個元素組成的view
(類模板) (範圍介面卡物件)[編輯]
接受一個由類似對的值組成的view,並生成一個由每對的第二個元素組成的view
(類模板) (範圍介面卡物件)[編輯]
一個view,它將適配序列的每個元素對映到元素的索引和值的元組
(類模板) (範圍介面卡物件)[編輯]
一個由引用到適配檢視對應元素的元組組成的 view
(類模板) (定製點物件)[編輯]
一個由轉換函式應用於適配檢視中對應元素的結果組成的 view
(類模板) (定製點物件)[編輯]
一個 view,由適配檢視相鄰元素的引用元組組成
(類模板) (範圍介面卡物件)[編輯]
一個 view,由對適配檢視的相鄰元素應用轉換函式的結果組成
(類模板) (範圍介面卡物件)[編輯]
一個 view 的範圍,它是另一個 view 元素的 N 大小的非重疊連續塊
(類模板) (範圍介面卡物件)[編輯]
一個view,其Mth元素是一個覆蓋另一個view的Mth到(M + N - 1)th元素的view
(類模板) (範圍介面卡物件)[編輯]
view分割成子範圍,位於給定謂詞返回false的每對相鄰元素之間
(類模板) (範圍介面卡物件)[編輯]
一個 view,由另一個 view 的元素組成,每次前進 N 個元素
(類模板) (範圍介面卡物件)[編輯]
一個view,由適配檢視的n元笛卡爾積計算出的元組組成
(類模板) (定製點物件)[編輯]
一個view,它快取其底層序列的最後訪問元素
(類模板) (範圍介面卡物件)[編輯]
view轉換為僅是input_range且非common_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*/ 是一個用於有條件地將 const 限定符應用於型別 T 的簡寫。

[編輯] 類整數型別輔助模板

template< /*is-integer-like*/ T >
using /*make-signed-like-t*/<T> = /* 參見描述 */;
(1) (僅作說明*)
template< /*is-integer-like*/ T >
using /*make-unsigned-like-t*/<T> = /* 參見描述 */;
(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& /*possibly-const-range*/(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 /*as-const-pointer*/( const T* p ) noexcept
{
    return p;

}
(2) (僅作說明*)

一些範圍訪問自定義點物件是根據這些僅用於闡述的函式模板指定的。

1) /*possibly-const-range*/ 返回 r 的 const 限定版本,如果 const R 建模 input_range;否則,不進行任何型別轉換返回 r
2) /*as-const-pointer*/ 返回指向 const 型別物件的指標。

[編輯] 範圍介面卡輔助函式

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*/f 應用於 tuple 的每個元素,不返回任何內容。
3) /*as-lvalue*/ 將右值 t 作為左值轉發。

[編輯] 輔助概念

以下僅用於闡述的概念用於幾種型別,但它們不是標準庫介面的一部分。

template< class R >

concept /*simple-view*/ =
    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 /*has-arrow*/ =
    ranges::input_iterator<I> &&

    (std::is_pointer_v<I> || requires(const I i) { i.operator->(); });
(2) (僅作說明*)
template< class T, class U >

concept /*different-from*/ =

    !std::same_as<std::remove_cvref_t<T>, std::remove_cvref_t<U>>;
(3) (僅作說明*)
template< class R >

concept /*range-with-movable-references*/ =
    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 /*all-random-access*/ =
    (ranges::random_access_range

         <std::conditional_t<C, const Views, Views>> && ...);
(5) (僅作說明*)
template< bool C, class... Views >

concept /*all-bidirectional*/ =
    (ranges::bidirectional_range

         <std::conditional_t<C, const Views, Views>> && ...);
(6) (僅作說明*)
template< bool C, class... Views >

concept /*all-forward*/ =
    (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) Ranges 庫和 受限演算法
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)
移除間接可呼叫概念中的 common reference 要求
__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_hintranges::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,
ranges::adjacent_view,
ranges::adjacent_transform_view

[編輯] 示例

#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; };
 
    // the "pipe" syntax of composing the views:
    for (int i : ints | std::views::filter(even) | std::views::transform(square))
        std::cout << i << ' ';
 
    std::cout << '\n';
 
    // a traditional "functional" composing syntax:
    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-rangeas-const-pointer
未宣告為 noexcept
宣告為 noexcept
LWG 4027 C++23 對於已建模 constant_range 的範圍,possibly-const-range 不會新增 const-限定符
對於已建模 constant_range 的範圍,possibly-const-range 不會新增 const-限定符
為這些範圍新增 const-限定符
為這些範圍
LWG 4112 C++20 has-arrow 不要求 i 為 const-限定符 要求

[編輯] 參見