Skip to content

Istruzioni di Iterazione (Cicli e Ranges)

Le Iteration Statements eseguono ciclicamente un’istruzione. Conosciamo i costrutti tipici: while, do-while (che garantisce sempre un primo tick di iterazione a priori), ed i classici cicli for con l’indice manuale (for(int i = 0; i < N; i++)).

In C++ l’iterazione index-based degli array manuale è un pattern anni ‘50 (“c-style”) altamente soggetto a Off-by-One Errors (errori di calcolo del limite dell’array). La panacea si chiama: Ranged-based for Loops.

Itera attraverso una gamma (range) di valori senza esporsi ad un indice esplicito. Qualsiasi costrutto che supporti la restituzione di un inizio e una fine sequenziale in C++ (come tutti i Container della Libreria Standard, o gli array statici crudi) può essere iniettato in un for:

int arr[] = {10, 20, 30};
// range-declaration : range-expression
for (const auto& elemento : arr) {
printf("%d\\n", elemento);
}

Estrarrà ordinatamente il valore, e ci fermerà in sicurezza.

Possiamo fare in modo che qualsiasi nostra classe esotica possa venire iterata in un ciclo for(auto x : obj). Sotto al cofano, il Ranged For Loop C++ chiede tacitamente ai tuoi oggetti tre requisiti di interfaccia:

  1. Il tuo oggetto-contenitore deve possedere un metodo begin() e un metodo end(). Entrambi devono restituire un oggetto “Iteratore”.
  2. L’Oggetto Iteratore (Il puntatore fittizio) ritornato, dovrà sovrascrivere l’operatore di deferenziazione (operator*) in modo che il ciclo for possa prelevarne il valore in corso.
  3. L’Oggetto Iteratore dovrà sovrascrivere l’operatore di comparazione Not-Equals (operator!=) per capire se ha impattato contro la end(), e l’operatore di incremento prefix (operator++) per poter avanzare verso l’elemento successivo.

Imponendo questa faticosa architettura alla classe FibonacciRange, il programmatore che ne utilizzerà il pacchetto non dovrà scriversi nessuna logica di conteggio o interazione manuale, godendosi una banale estrazione pulita in un ciclo for.