Generators

Learn about generators, their use, and their implementation, along with iterators and promises.

A generator is a type of coroutine that yields values back to its caller. For example, at the beginning of this chapter, we demonstrated how the generator iota() yielded increasing integer values. By implementing a general-purpose generator type that can act as an iterator, we can simplify the work of implementing iterators that are compatible with range-based for-loops, standard library algorithms, and ranges. Once we have a generator template class in place, we can reuse it.

So far in this course, we have mostly seen iterators when accessing container elements and using standard library algorithms. However, an iterator does not have to be tied to a container. It’s possible to write iterators that produce values.

Implementing a generator

The generator we are about to implement is based on the generator from the CppCoro library. The generator template is intended to be used as a coroutine return type that produces a sequence of values. It should be possible to use objects of this type with a range-based for-loop and standard algorithms that accept iterators and ranges. To make this possible, we will implement three components:

  • The Generator, which is the return object
  • The Promise, which acts as the coroutine controller
  • The Iterator, which is the interface between the client and the Promise

These three types are tightly coupled and the relationships between them and the coroutine state are presented in the following diagram:

Get hands-on with 1400+ tech skills courses.