名稱空間
變體
操作

std::generator

來自 cppreference.com
< cpp‎ | 協程
 
 
 
協程支援
協程特質
協程控制代碼
無操作協程
平凡可等待物件
範圍生成器 (Range generators)
generator
(C++23)
 
範圍庫 (Ranges library)
範圍介面卡 (Range adaptors)
 
 
定義於標頭檔案 <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 提供一個 view,用於透過求值 協程 產生元素。
2) 使用 多型分配器generator 的便捷別名模板。

std::generator 透過重複恢復返回它的協程來生成元素序列。每次求值 `co_yield` 語句時,協程生成序列中的一個元素。當 `co_yield` 語句的形式為 co_yield ranges::elements_of(rng) 時,range rng 中的每個元素都依次作為序列的一個元素被生成。

std::generator 模仿 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 是一個引用型別,或者一個 cv 不合格的物件型別,它模仿 copy_constructible
-
RRef 表示 std::remove_reference_t<reference >&&,如果 reference 是引用型別,否則為 reference

如果這些型別要求中的任何一個不滿足,則程式格式錯誤。

[編輯] 資料成員

成員 定義
active_ (私有)

在內部,std::generator 的每個活動例項都與一個堆疊相關聯(處理方式如同透過型別為 std::unique_ptr<std::stack<std::coroutine_handle<>>> 的物件)。

  • 當呼叫 begin 時,會建立一個新堆疊並將生成器新增到堆疊中。
  • 當在生成器體中求值 co_yield ranges::elements_of(rng) 時,rng 會被轉換為生成器並新增到包含 enclosing 生成器的堆疊中。
  • 當生成器迭代器被遞增時,相關堆疊頂部的協程會恢復。
  • 當生成器完成時(即當呼叫 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)
返回範圍常量迭代器的哨兵
(std::ranges::view_interface<D> 的公有成員函式) [編輯]
返回派生檢視是否非空,僅當 ranges::empty 適用於它時提供
(std::ranges::view_interface<D> 的公有成員函式) [編輯]

[編輯] 巢狀類

承諾型別
(公有成員類)
迭代器型別
(僅用於說明的成員類*)

[編輯] 注意

特性測試 標準 特性
__cpp_lib_generator 202207L (C++23) std::generator – 用於 range 的同步 協程 生成器

[編輯] 示例

#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]

[編輯] 另請參閱

建立一個協程控制代碼,當恢復或銷燬時沒有可觀察到的效果
(函式) [編輯]