Namespaces
Variants

std::generator

来自 zh.cppreference.net
 
 
 
协程支持
协程特性
协程句柄
无操作协程
平凡可等待
范围生成器
(C++23)
 
范围库
范围适配器
 
 
定义于头文件 <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 的 coroutine 求值所产生的元素视图。
2) 使用 generator 的便捷别名模板 多态分配器。

一个 std::generator 通过反复恢复从其返回的协程来生成元素序列。 每次求值 co_yield 语句时,协程生成序列的一个元素。 当 co_yield 语句的形式为 co_yield ranges::elements_of(rng) 时,range rng 的每个元素被依次生成为序列的一个元素。

std::generator 满足 view 和 input_range。

为 std::generator 添加特化的程序行为未定义。

模板参数

Ref - 生成器的引用类型( ranges::range_reference_t )。若 V 为 void ,则引用类型与值类型均从 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 。

如果这些类型要求中的任何一个未得到满足,则程序是非良构的。

数据成员

成员 描述
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
(公开成员函数)
继承自 ranges::view_interface
返回派生视图是否为空,仅当它满足 sized_range 或 forward_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 – 用于 范围 的同步 协程 生成器

示例

#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 范围生成器 [coro.generator]

参见

创建一个在恢复或销毁时无可见效果的协程句柄
(函数)