Ranges 程式庫 (自 C++20 起)
Ranges 程式庫是演算法與迭代器程式庫的擴充與泛化,透過使其具備組合性並減少錯誤發生,使其功能更強大。
該程式庫建立並操作範圍「檢視 (views)」,這是一種間接表示可迭代序列(「範圍 (ranges)」)的輕量級物件。範圍是基於以下概念的抽象:
-
[begin,end)– 迭代器對,例如透過容器隱式轉換而成的範圍。所有接受迭代器對的演算法現在都有接受範圍的重載版本(例如 ranges::sort) - begin
+[0,size)– 計數序列,例如由 views::counted 回傳的範圍 -
[begin,predicate)– 條件終止序列,例如由 views::take_while 回傳的範圍 -
[begin,..)– 無界序列,例如由 views::iota 回傳的範圍
Ranges 程式庫包含範圍演算法(立即套用於範圍)與範圍適配器(延遲套用於檢視)。適配器可以組合成管線 (pipelines),以便在其檢視被迭代時才執行動作。
| 定義於標頭檔 <ranges> |
||
| namespace std { namespace views = ranges::views; |
(自 C++20 起) | |
提供命名空間別名 std::views 作為 std::ranges::views 的簡寫。
| 定義於命名空間
std::ranges | ||
範圍存取 | ||
| 定義於標頭檔
<ranges> | ||
| 定義於標頭檔
<iterator> | ||
| (C++20) |
回傳指向範圍開頭的迭代器 (自定義點物件) | |
| (C++20) |
回傳表示範圍結尾的哨兵 (sentinel) (自定義點物件) | |
| (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> | ||
| (C++20) |
一種佔位符型別,表示不應回傳迭代器或 subrange,因為它會是懸空的(類別) | |
獲取 borrowed_range 的迭代器型別或 subrange 型別(別名範本) | ||
其他公用程式 | ||
| 定義於標頭檔
<ranges> | ||
| (C++23) |
標記一個範圍使其被視為序列而非單個值 (類別範本) | |
範圍概念 | ||
| 定義於標頭檔
<ranges> | ||
| (C++20) |
指定一個型別為範圍,即它提供 begin 迭代器與 end 哨兵(概念) | |
| (C++20) |
指定一個型別為 range,且從其運算式獲取的迭代器可以安全回傳,無懸空危險(概念) | |
| 指定一個範圍可以在常數時間內估計其大小 (概念) | ||
| (C++20) |
指定一個範圍可以在常數時間內獲悉其大小 (概念) | |
| (C++20) |
指定一個範圍為檢視,即它具有常數時間的複製/移動/賦值 (概念) | |
| (C++20) |
指定其迭代器型別滿足 input_iterator 的範圍(概念) | |
| (C++20) |
指定其迭代器型別滿足 output_iterator 的範圍(概念) | |
| (C++20) |
指定其迭代器型別滿足 forward_iterator 的範圍(概念) | |
| (C++20) |
指定其迭代器型別滿足 bidirectional_iterator 的範圍(概念) | |
| (C++20) |
指定其迭代器型別滿足 random_access_iterator 的範圍(概念) | |
| (C++20) |
指定其迭代器型別滿足 contiguous_iterator 的範圍(概念) | |
| (C++20) |
指定範圍具有相同的迭代器與哨兵型別 (概念) | |
| (C++20) |
指定 range 安全轉換為 view 的要求(概念) | |
| (C++23) |
指定範圍具有唯讀元素 (概念) | |
範圍轉換 | ||
| 定義於標頭檔
<ranges> | ||
| (C++23) |
從輸入範圍構造一個新的非檢視物件 (函式範本) | |
檢視 | ||
| 定義於標頭檔
<ranges> | ||
| (C++20) |
用於定義 view 的輔助類別範本,使用奇異遞迴範本模式 (CRTP)(類別範本) | |
| (C++20) |
將一個迭代器-哨兵對結合成一個 view(類別範本) | |
[編輯] 範圍工廠
| 定義於標頭檔
<ranges> | |
| 定義於命名空間
std::ranges | |
一個不含元素的空 view(類別範本) (變數範本) | |
包含指定值的單一元素的 view(類別範本) (自定義點物件) | |
| (C++20) |
由重複遞增初始值產生的序列所組成的 view(類別範本) (自定義點物件) |
由重複產生相同值而產生的序列所組成的 view(類別範本) (自定義點物件) | |
由在相關輸入串流上連續套用 operator>> 獲取的元素組成的 view(類別範本) (自定義點物件) | |
[編輯] 範圍適配器
| 定義於標頭檔
<ranges> | |
| 定義於命名空間
std::ranges | |
| 用於定義範圍適配器閉包物件的輔助基底類別範本 (類別範本) | |
| (C++20) |
包含 range 之所有元素的 view(別名範本) (範圍適配器物件) |
| (C++20) |
其他某個 range 元素的 view(類別範本) |
| (C++20) |
具有某個 range 獨佔所有權的 view(類別範本) |
一個將每個元素轉型為右值 (rvalue) 的序列 view(類別範本) (範圍適配器物件) | |
由 range 中滿足謂詞 (predicate) 的元素組成的 view(類別範本) (範圍適配器物件) | |
對序列中每個元素套用轉換函式的 view(類別範本) (範圍適配器物件) | |
| (C++20) |
由另一個 view 的前 N 個元素組成的 view(類別範本) (範圍適配器物件) |
由另一個 view 的初始元素組成的 view,直到遇到第一個使謂詞回傳 false 的元素為止(類別範本) (範圍適配器物件) | |
| (C++20) |
由另一個 view 的元素組成,並跳過前 N 個元素的 view(類別範本) (範圍適配器物件) |
由另一個 view 的元素組成的 view,跳過初始元素子序列,直到第一個使謂詞回傳 false 的元素為止(類別範本) (範圍適配器物件) | |
| (C++20) |
由展平 (flattening) 範圍的 view 所獲得的序列組成的 view(類別範本) (範圍適配器物件) |
由展平範圍的檢視所獲得的序列組成的 view,且在各元素之間插入分隔符(類別範本) (範圍適配器物件) | |
對另一個 view 使用分隔符分割後獲得的子範圍所構成的 view(類別範本) (範圍適配器物件) | |
對另一個 view 使用分隔符分割後獲得的子範圍所構成的 view(類別範本) (範圍適配器物件) | |
由被適配檢視之串接 (concatenation) 組成的 view(類別範本) (自定義點物件) | |
| (C++20) |
從迭代器與計數建立一個子範圍 (subrange) (自定義點物件) |
將 view 轉換為 common_range(類別範本) (範圍適配器物件) | |
一個以反向順序迭代另一個雙向檢視之元素的 view(類別範本) (範圍適配器物件) | |
將 view 轉換為 constant_range(類別範本) (範圍適配器物件) | |
接受由 類元組 (tuple-like) 數值組成的 view 與數字 N,並產生每個元組之第 N 個元素的 view(類別範本) (範圍適配器物件) | |
| (C++20) |
接受由類對值 (pair-like) 組成的 view,並產生每對之第一個元素的 view(類別範本) (範圍適配器物件) |
接受由類對值組成的 view,並產生每對之第二個元素的 view(類別範本) (範圍適配器物件) | |
一個將適配序列的每個元素對映到包含該元素位置及其數值之元組的 view(類別範本) (範圍適配器物件) | |
| (C++23) |
由各適配檢視之對應元素的參考所構成之元組組成的 view(類別範本) (自定義點物件) |
由對各適配檢視之對應元素套用轉換函式的結果所組成的 view(類別範本) (自定義點物件) | |
由適配檢視之相鄰元素的參考所構成之元組組成的 view(類別範本) (範圍適配器物件) | |
由對適配檢視之相鄰元素套用轉換函式的結果所組成的 view(類別範本) (範圍適配器物件) | |
由另一個 view 的元素構成的大小為 N、不重疊連續區塊 (chunks) 之 views 所構成的範圍(類別範本) (範圍適配器物件) | |
一個 view,其第 M 個元素為另一個 view 之第 M 到第 (M + N - 1) 個元素的 view(類別範本) (範圍適配器物件) | |
在每對使給定謂詞回傳 false 的相鄰元素之間,將 view 分割為多個子範圍(類別範本) (範圍適配器物件) | |
由另一個 view 的元素組成,每次跨越 N 個元素的 view(類別範本) (範圍適配器物件) | |
由各適配檢視之 n 元笛卡兒積 (cartesian product) 計算結果元組所組成的 view(類別範本) (自定義點物件) | |
快取其底層序列最後一次存取元素的 view(類別範本) (範圍適配器物件) | |
將 view 轉換為僅為 input_range 且非 common_range 的範圍(類別範本) (範圍適配器物件) | |
[編輯] 範圍生成器 (自 C++23 起)
| 定義於標頭檔
<generator> | |
| 定義於命名空間
std | |
| (C++23) |
表示同步協程 (coroutine) 生成器的 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> = /* 參見說明 */; |
(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 ) |
(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& /*possibly-const-range*/(R& r) noexcept |
(1) | (僅供說明*) |
template< class T > constexpr auto /*as-const-pointer*/( 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 /*simple-view*/ = |
(1) | (僅供說明*) |
template< class I > concept /*has-arrow*/ = |
(2) | (僅供說明*) |
template< class T, class U > concept /*different-from*/ = |
(3) | (僅供說明*) |
template< class R > concept /*range-with-movable-references*/ = |
(4) | (僅供說明*) |
template< bool C, class... Views > concept /*all-random-access*/ = |
(5) | (僅供說明*) |
template< bool C, class... Views > concept /*all-bidirectional*/ = |
(6) | (僅供說明*) |
template< bool C, class... Views > concept /*all-forward*/ = |
(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; }; // 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++ 標準。
| DR | 應用於 | 出版時的行為 | 正確的行為 |
|---|---|---|---|
| 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 的範圍不會添加 const 限定 |
會為該類範圍 添加 const 限定 |
| LWG 4112 | C++20 | has-arrow 未要求 i 具有 const 限定 |
要求 |