Namespaces
Variants

std:: generator

From cppreference.net
Utilities library
Coroutine support
Coroutine traits
Coroutine handle
No-op coroutines
Trivial awaitables
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 的便捷别名模板,采用 polymorphic allocator

一个 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
(公开成员函数)
继承自 std::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]

参见

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