命名空间
变体
操作

std::generator

来自 cppreference.cn
< 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]

[编辑] 另请参阅

创建一个协程句柄,当恢复或销毁时没有可观察到的效果
(函数) [编辑]