命名空间
变体
操作

std::generator

来自 cppreference.com
< cpp‎ | coroutine
 
 
实用程序库
语言支持
类型支持 (基本类型,RTTI)
库特性测试宏 (C++20)
动态内存管理
程序实用程序
协程支持 (C++20)
可变参数函数
调试支持
(C++26)
三元比较
(C++20)
(C++20)(C++20)(C++20)
(C++20)(C++20)(C++20)
通用实用程序
日期和时间
函数对象
格式化库 (C++20)
(C++11)
关系运算符 (C++20 中已弃用)
整数比较函数
(C++20)(C++20)(C++20)   
(C++20)
交换类型操作
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
通用词汇类型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
基本字符串转换
(C++17)
(C++17)

 
协程支持
协程特性
协程句柄
空操作协程
琐碎的可等待对象
范围生成器
generator
(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 提供了对从 协程 评估中产生的元素的 视图
2) 使用 多态分配器generator 的便利别名模板。

std::generator 通过反复从返回它的协程中恢复协程来生成一系列元素。每次评估 co_yield 语句时,协程都会生成序列中的一个元素。当 co_yield 语句的形式为 co_yield ranges::elements_of(rng) 时,范围 rng 中的每个元素都会作为序列中的元素依次生成。

std::generator 模拟 视图输入范围

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

内容

[编辑] 模板参数

Ref - 生成器的引用类型(ranges::range_reference_t)。如果 Vvoid,则引用类型和值类型都从 Ref 推断。
V - 生成器的值类型(ranges::range_value_t),或 void
Allocator - 分配器类型或 void

如果 Allocator 不是 void,则如果 Allocator 不满足 Allocator 要求,则行为未定义。

[edit] 成员类型

成员 定义
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>;
(仅供说明的成员类型*)
生成 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

如果这些类型要求中的任何一个不满足,则程序格式错误。

[edit] 数据成员

成员 定义
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> 的句柄
(仅供说明的成员对象*)

[edit] 成员函数

构造一个 generator 对象
(公共成员函数) [edit]
有效地销毁所有生成的 generator 的整个堆栈
(公共成员函数) [edit]
将一个 generator 对象赋值给另一个
(公共成员函数) [edit]
恢复最初挂起的协程并返回指向其句柄的迭代器
(公共成员函数) [edit]
返回 std::default_sentinel
(公共成员函数) [edit]
std::ranges::view_interface 继承
返回派生视图是否为空。如果它满足 sized_rangeforward_range,则提供。
(std::ranges::view_interface<D> 的公共成员函数) [edit]
(C++23)
返回指向范围开头的常量迭代器。
(std::ranges::view_interface<D> 的公共成员函数) [edit]
(C++23)
返回范围常量迭代器的哨兵。
(std::ranges::view_interface<D> 的公共成员函数) [edit]
返回派生视图是否不为空。如果 ranges::empty 可用于它,则提供。
(std::ranges::view_interface<D> 的公共成员函数) [edit]

[edit] 嵌套类

承诺类型
(公共成员类)
迭代器类型
(仅供说明的成员类*)

[edit] 注释

功能测试 Std 功能
__cpp_lib_generator 202207L (C++23) std::generator - 用于 范围 的同步 协程 生成器

[edit] 示例

#include <generator>
#include <iostream>
 
template<typename T>
struct Tree
{
    T value;
    Tree *left{}, *right{};
 
    std::generator<const T&> traverse_inorder() const
    {
        if (left)
            for (const T& x : left->traverse_inorder())
                co_yield x;
 
        co_yield value;
        if (right)
            for (const T& x : right->traverse_inorder())
                co_yield x;
    }
};
 
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

[edit] 参考文献

  • C++23 标准(ISO/IEC 14882:2024)
  • 26.8 范围生成器 [coro.generator]

[edit] 另请参阅

创建一个协程句柄,该句柄在恢复或销毁时不会产生任何可观察到的影响
(函数) [edit]