This page covers the basic usage of stackless coroutines.
The coroutines that are part of the C++ 20 standard will be used to implement stackless coroutines.
The page goes over the basic usage of stackless coroutines and explains the different ways the C++ 20 standard implementation can be used.
Readers familiar with coroutines and the differences between stackful and stackless coroutines might find starting with the producer-consumer page covering stackless coroutines more useful.
Any function in C++ 20 that uses co_yield, co_await or co_return is considered a coroutine.
These coroutines require a particular return type that will be used to handle calls to the coroutine.
In most use cases, it is possible to use a library that handles the return type to make working with coroutines easier.
Another option is to create a custom return type that the coroutines can use.
This custom return type was chosen during the research of the topic.
This choice was made because it offered complete control over the behaviour of the coroutine and helped get a better understanding of the inner workings of C++ stackless coroutines.
In this basic example, the return type of all coroutines will always be CoroutineHandler.
CoroutineHandler is a custom-written class based on the example provided in the documentation on the website cppreference [1].
The return type is not discussed on this page because it requires a more in-depth explanation than fits the basics page.
The full explanation of the CoroutineHandler class can be found on the Stackless coroutines - CoroutineHandler page.
The only important thing about this CoroutineHandler class to understand the basic examples is that this return type can be saved when creating a coroutine and will be used to call the coroutine.
A custom class containing all the example functions will be used.
This usage of a class is done because the creation of coroutines works differently for static and non-static functions.
When the function the coroutine should run is not part of any class, the same code as the example for static functions can be used.
The class is defined as follows in the header file:
The basic example will create a coroutine and call it.
The main function will create the coroutine.
Coroutine are created by calling the coroutine like a function and saving the return value using the CoroutineHandler class.
The coroutine itself will have a return type of CoroutineHandler.
Inside the body of the coroutine, one of three statements must be present at least once for the function to become a coroutine.
These statements are co_yield, co_await and co_return.
In this example, the co_yield statement was used.
Keep in mind that the co_yield statement always expects a parameter.
The type expected by the CoroutineHandler in this example is a boolean.
The co_yield will thus use the value true as its parameter.
Creating a non-static coroutine works the same as calling a non-static function.
Adding parameters to the coroutines also works the same way as adding parameters to a function.