Implémenter un générateur simple
Construire une coroutine génératrice qui produit des valeurs de manière différée
Implémenter un générateur simple est une leçon C++ Academy gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C++ Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C++ Academy comprend 4 leçons au total.
Les générateurs comme coroutines
Un générateur est une coroutine qui produit des valeurs une par une. Chaque appel au générateur produit la valeur suivante, puis suspend son exécution.
Le type Generator
Définissez une classe contenant un promise_type imbriqué. Le compilateur l’utilise pour gérer l’état de la coroutine.
template <typename T>
struct Generator {
struct promise_type {
T current_value;
Generator get_return_object() {
return Generator{std::coroutine_handle<promise_type>::from_promise(*this)};
}
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_void() {}
std::suspend_always yield_value(T value) {
current_value = value;
return {};
}
void unhandled_exception() { std::terminate(); }
};
std::coroutine_handle<promise_type> h;
// ... constructors, destructor, next() ...
};Utiliser le générateur
Une fois définis, les générateurs s’utilisent comme la production de valeurs avec yield en Python.
Generator<int> counting() {
int n = 0;
while (true) co_yield n++;
}
auto g = counting();
for (int i = 0; i < 5; ++i) {
std::cout << g.next() << " ";
}
// 0 1 2 3 4coroutine_handle
Le compilateur renvoie un std::coroutine_handle. Il représente la coroutine suspendue : vous pouvez appeler resume(), destroy() ou vérifier done().
Points de suspension
Chaque co_yield suspend l’exécution. Lorsque l’appelant appelle resume(), l’exécution se poursuit jusqu’au point de suspension suivant ou jusqu’à la fin de la coroutine.
initial_suspend et final_suspend
Deux points de personnalisation :
initial_suspend— renvoiesuspend_alwayspour un démarrage différé oususpend_neverpour un démarrage immédiatfinal_suspend— contrôle le nettoyage. Renvoie généralementsuspend_alwayspour permettre une destruction correcte
std::generator de C++23
C++23 a ajouté std::generator dans <generator>. Vous n’avez plus besoin de créer vous-même ce type pour les cas courants.
#include <generator>
std::generator<int> counting() {
int n = 0;
while (true) co_yield n++;
}Boucle for fondée sur une plage
Si le type du générateur prend en charge le début et la fin, la boucle for fondée sur une plage fonctionne directement.
for (int x : counting()) {
if (x >= 10) break;
std::cout << x;
}Sémantique par extraction et par émission
Les générateurs sont fondés sur la demande : l’appelant pilote l’itération. Les coroutines fondées sur l’émission sont des tâches asynchrones.
Cas d’utilisation
Les générateurs sont particulièrement adaptés aux usages suivants :
- Séquences différées : nombres de Fibonacci, nombres premiers, lecteurs de fichiers ligne par ligne
- Diffusion de données sans matérialisation
- Parcours de structures arborescentes
Considérations liées à la mémoire
Le cadre de coroutine est alloué par défaut sur le tas. Le compilateur peut supprimer cette allocation lorsque l’extension en ligne le permet : mesurez les performances lorsque cela est important.
Bibliothèques à découvrir
Pour apprendre, cppcoro de Lewis Baker propose des types de générateurs et de tâches bien documentés. Boost.Asio fournit des entrées-sorties adaptées aux coroutines. À partir de C++23, la bibliothèque standard offre également une prise en charge.
Vérification rapide
Quel est le type de la bibliothèque standard C++23 pour les coroutines génératrices ?
Récapitulatif
Une coroutine génératrice produit des valeurs de manière différée avec co_yield. Implémentez-la avec une classe contenant un promise_type. C++23 a standardisé std::generator. Les générateurs sont particulièrement adaptés aux séquences différées et à la diffusion de données.
Questions Fréquemment Posées
La leçon « Implémenter un générateur simple » est-elle gratuite ?
Oui — le texte complet de « Implémenter un générateur simple » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C++ Academy, passe à CoddyKit PRO. Le cours C++ Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Implémenter un générateur simple » ?
Construire une coroutine génératrice qui produit des valeurs de manière différée Tu pratiques C++ Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer C++ Academy ?
Aucune expérience préalable n'est requise. C++ Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Implémenter un générateur simple » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon C++ Academy ?
Oui. Chaque leçon C++ Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Concepts des coroutines : co_await, co_yield, co_return
- Implémenter un générateur simple
- Tâches asynchrones et types awaiter
- Allocation de la trame d’une coroutine