命名空間
變體
動作

std::generator

出自 cppreference.com
< cpp‎ | coroutine
 
 
 
協程支援
協程特性
協程句柄
空操作(No-op)協程
平凡可等待物件
範圍生成器
generator
(C++23)
 
Ranges 程式庫
範圍適配器
 
 
定義於標頭檔 <generator>
template<

    class Ref,
    class V = void,
    class Allocator = void >
class generator

    : public ranges::view_interface<generator<Ref, V, Allocator>>
(1) (自 C++23 起)
namespace pmr {

    template< class Ref, class V = void >
    using generator =
        std::generator<Ref, V, std::pmr::polymorphic_allocator<>>;

}
(2) (自 C++23 起)
1) 類別模板 std::generator 展示了一個由協程 (coroutine) 求值所產出元素的 view
2) 使用多型配置器 (polymorphic allocator)generator 之方便別名模板。

std::generator 透過反覆恢復其所回傳的協程來產生元素序列。每次求值 co_yield 陳述式時,協程就會產出序列中的一個元素。當 co_yield 陳述式形式為 co_yield ranges::elements_of(rng) 時,range rng 的每個元素會被依序產出作為序列的一個元素。

std::generator 實現了 (models) viewinput_range

若程式為 std::generator 增加特化,其行為是未定義的。

目錄

[編輯] 模板參數

Ref - 生成器的參照型別 (ranges::range_reference_t)。若 Vvoid,則參照型別與值型別皆由 Ref 推導而來
V - 生成器的值型別 (ranges::range_value_t),或為 void
配置器 (Allocator) - 配置器型別或 void

Allocator 不為 void,且 Allocator 未滿足 Allocator 需求,則行為未定義。

[編輯] 成員型別

成員 定義
value (私有) std::conditional_t<std::is_void_v<V>, std::remove_cvref_t<Ref>, V>;
(僅供展示的成員型別*)
reference (私有) std::conditional_t<std::is_void_v<V>, Ref&&, Ref>;
(僅供展示的成員型別*)
yielded std::conditional_t<std::is_reference_v<reference >, reference, const reference &>
類型要求
-
std::allocator_traits<Allocator>::pointer 為一個指標型別。
-
value 為一個 cv 限定詞不修飾的物件型別。
-
reference 為參照型別,或是滿足 copy_constructible 的 cv 限定詞不修飾的物件型別。
-
RRef 表示 std::remove_reference_t<reference >&&(若 reference 為參照型別),否則為 reference 本身。

若不滿足上述任一型別需求,則程式語法不合法 (ill-formed)。

[編輯] 資料成員

成員 定義
active_ (私有)

在內部,每個 std::generator 的活躍實例都會關聯一個堆疊(處理方式如同 std::unique_ptr<std::stack<std::coroutine_handle<>>> 型別的物件)。

  • 當呼叫 begin 時,會建立一個新的堆疊並將生成器加入該堆疊中。
  • 當在生成器主體中求值 co_yield ranges::elements_of(rng) 時,rng 會被轉換為生成器,並被加入包含封裝生成器的堆疊中。
  • 當生成器迭代器被遞增時,關聯堆疊頂部的協程將被恢復。
  • 當生成器完成時(即當呼叫 promise_type::final_suspend 時),它會從堆疊中移除。
    (僅用於闡述的成員物件*)
coroutine_ (私有) 一個 std::coroutine_handle<promise_type> 型別的控制代碼
(僅用於闡述的成員物件*)

[編輯] 成員函式

建構一個 generator 物件
(公開成員函式) [編輯]
有效地銷毀整個已產出 generator 的堆疊
(公開成員函式) [編輯]
指派一個 generator 物件
(公開成員函式) [編輯]
恢復最初暫停的協程,並回傳一個指向其控制代碼的迭代器
(公開成員函式) [編輯]
回傳 std::default_sentinel
(公開成員函式) [編輯]
繼承自 std::ranges::view_interface
回傳派生視圖是否為空,僅在滿足 sized_rangeforward_range 時提供
(std::ranges::view_interface<D> 的公開成員函式) [編輯]
(C++23)
回傳指向範圍起始處的常數迭代器
(std::ranges::view_interface<D> 的公開成員函式) [編輯]
(C++23)
回傳該範圍常數迭代器的哨兵 (sentinel)
(std::ranges::view_interface<D> 的公開成員函式) [編輯]
回傳派生視圖是否非空,僅在 ranges::empty 適用於它時提供
(std::ranges::view_interface<D> 的公開成員函式) [編輯]

[編輯] 巢狀類別

promise 型別
(公開成員類別)
迭代器型別
(僅供展示的成員類別*)

[編輯] 附註

功能測試巨集 數值 標準 功能
__cpp_lib_generator 202207L (C++23) std::generator – 用於 ranges 的同步 協程生成器

[編輯] 範例

#include <generator>
#include <iostream>
 
template<typename T>
struct Tree
{
    T value;
    Tree *left{}, *right{};
 
    std::generator<const T&> traverse_inorder() const
    {
        if (left)
            co_yield std::ranges::elements_of(left->traverse_inorder());
 
        co_yield value;
 
        if (right)
            co_yield std::ranges::elements_of(right->traverse_inorder());
    }
};
 
int main()
{
    Tree<char> tree[]
    {
                                    {'D', tree + 1, tree + 2},
        //                            │
        //            ┌───────────────┴────────────────┐
        //            │                                │
                    {'B', tree + 3, tree + 4},       {'F', tree + 5, tree + 6},
        //            │                                │
        //  ┌─────────┴─────────────┐      ┌───────────┴─────────────┐
        //  │                       │      │                         │
          {'A'},                  {'C'}, {'E'},                    {'G'}
    };
 
    for (char x : tree->traverse_inorder())
        std::cout << x << ' ';
    std::cout << '\n';
}

輸出

A B C D E F G

[編輯] 參考資料

  • C++23 標準 (ISO/IEC 14882:2024)
  • 26.8 Range 生成器 [coro.generator]

[編輯] 參見

建立一個在恢復或銷毀時無可觀測副作用的協程句柄
(函式) [編輯]
English Deutsch 日本語 中文(简体) 中文(繁體)