Spec-Zone.ru › C++

std::generator

Определён в заголовке <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 моделирует view и input_range.

Поведение программы, добавляющей специализацию для std::generator, не определено.

Параметры шаблона

Ref - тип ссылки (ranges::range_reference_t) генератора. Если V равен void, тип ссылки и тип значения выводятся из Ref
V - тип значения (ranges::range_value_t) генератора или void
Allocator - тип аллокатора или void

Если Allocator не равен void, поведение не определено, если 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,constreference &>
Требования к типам
-std::allocator_traits<Allocator>::pointer является типом указателя.
-value является типом объекта без квалификаторов cv.
-reference является либо типом ссылки, либо типом объекта без квалификаторов cv, который моделирует copy_constructible.
-Пусть RRef обозначает std::remove_reference_t<reference >&&, если reference является типом ссылки, и reference в противном случае.
  • std::common_reference_with<reference &&,value &> моделируется.
  • std::common_reference_with<reference &&,RRef &&> моделируется.
  • std::common_reference_with<RRef &&,constvalue &> моделируется.

Программа некорректна, если какое-либо из этих требований к типам не выполнено.

Поля данных

Член Описание
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
(открытая функция-член)
operator=
присваивает объект generator
(открытая функция-член)
begin
возобновляет изначально приостановленную корутину и возвращает итератор к её дескриптору
(открытая функция-член)
end
возвращает std::default_sentinel
(открытая функция-член)
Унаследовано от std::ranges::view_interface
empty
возвращает признак того, что производное представление пусто; предоставляется только при выполнении требований sized_range или forward_range
(открытая функция-член класса std::ranges::view_interface<D>)
cbegin
(C++23)
возвращает константный итератор на начало диапазона
(открытая функция-член класса std::ranges::view_interface<D>)
cend
(C++23)
возвращает сентинел для константного итератора диапазона
(открытая функция-член класса std::ranges::view_interface<D>)
operator bool
возвращает признак того, что производное представление не пусто; предоставляется только если к нему применим ranges::empty
(открытая функция-член класса std::ranges::view_interface<D>)

Вложенные классы

promise_type
тип promise
(открытый класс-член)
iterator
тип итератора
(класс-член, используемый только для описания*)

Примечания

Макрос проверки поддержки возможностей Значение Стандарт Возможность
__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]

См. также

ranges::elements_of
(C++23)
помечает диапазон как последовательность, а не как отдельное значение
(шаблон класса)
noop_coroutine
(C++20)
создаёт дескриптор корутины, возобновление или уничтожение которого не имеет наблюдаемых эффектов
(функция)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/coroutine/generator

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API