0Pricing
C++ Academy · Lezione

Implementare un semplice generatore

Costruisca una coroutine generatrice che produca valori in modo lazy

Implementare un semplice generatore è una lezione C++ Academy gratuita su CoddyKit. Questa è la lezione 2 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C++ Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C++ Academy include 4 lezioni in totale.

I generatori come coroutine

Un generatore è una coroutine che restituisce i valori uno alla volta. Ogni chiamata al generatore produce il valore successivo e sospende l'esecuzione.

Il tipo generatore

Definisca una classe con un promise_type annidato. Il compilatore lo usa per gestire lo stato della 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() ...
};

Utilizzare il generatore

Una volta definiti, i generatori risultano naturali da usare, come yield in 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 4

coroutine_handle

Il compilatore restituisce uno std::coroutine_handle. Rappresenta la coroutine sospesa: può chiamare resume(), destroy() oppure verificare done().

Punti di sospensione

Ogni co_yield sospende l'esecuzione. Quando il chiamante invoca resume(), l'esecuzione continua fino al punto di sospensione successivo o alla fine della coroutine.

initial_suspend e final_suspend

Due punti di personalizzazione:

  • initial_suspend — restituisca suspend_always per un avvio lazy oppure suspend_never per un avvio eager
  • final_suspend — controlla la pulizia. In genere si usa suspend_always per una distruzione corretta

C++23 std::generator

C++23 ha aggiunto std::generator in <generator>. Per i casi comuni non è più necessario scrivere manualmente il tipo.

#include <generator>

std::generator<int> counting() {
    int n = 0;
    while (true) co_yield n++;
}

Ciclo for basato su intervallo

Se il tipo generatore supporta begin/end, il ciclo for basato su intervallo funziona automaticamente.

for (int x : counting()) {
    if (x >= 10) break;
    std::cout << x;
}

Semantica pull e push

I generatori sono basati sul pull: è il chiamante a controllare l'iterazione. Le coroutine basate sul push sono task asincroni.

Casi d'uso

I generatori sono ideali per:

  • Sequenze lazy, come Fibonacci, numeri primi e lettori di file riga per riga
  • Streaming di dati senza materializzazione
  • Iterazione su strutture ad albero

Considerazioni sulla memoria

Per impostazione predefinita, il coroutine frame viene allocato sull'heap. Il compilatore può eliminare l'allocazione quando l'inlining lo consente: misuri le prestazioni quando sono importanti.

Librerie da esplorare

Per imparare, cppcoro di Lewis Baker offre tipi per generatori e task ben documentati. Boost.Asio fornisce I/O compatibile con le coroutine. A partire da C++23 è disponibile anche il supporto della libreria standard.

Verifica rapida

Qual è il tipo della libreria standard C++23 per le coroutine generatore?

Riepilogo

Una coroutine generatore restituisce valori in modo lazy con co_yield. La si implementa con una classe che contiene un promise_type. C++23 ha standardizzato std::generator. I generatori sono ideali per le sequenze lazy e lo streaming.

Domande Frequenti

La lezione «Implementare un semplice generatore» è gratuita?

Sì — il testo completo di «Implementare un semplice generatore» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C++ Academy, passa a CoddyKit PRO. Il corso C++ Academy include 4 lezioni in totale.

Cosa imparerò in «Implementare un semplice generatore»?

Costruisca una coroutine generatrice che produca valori in modo lazy Eserciti C++ Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare C++ Academy?

Non è richiesta alcuna esperienza precedente. C++ Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 4.

Quanto tempo richiede la lezione «Implementare un semplice generatore»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione C++ Academy?

Sì. Ogni lezione C++ Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Concetti delle coroutine: co_await, co_yield, co_return
  2. Implementare un semplice generatore
  3. Attività asincrone e tipi awaiter
  4. Allocazione del frame delle coroutine
← Torna a C++ Academy