Skip to content

Parametri Non-Tipo e Template Variadici

Finora abbiamo visto i type template parameters (introdotti da typename o class). Esiste però una seconda potentissima categoria: i Non-Type Template Parameters.

Un parametro di template non di tipo agisce come segnaposto per un valore, non per un tipo. Questo valore deve essere valutabile a tempo di compilazione. Le casistiche ammesse includono interi (int, size_t, ecc.), enum, referenze e nullptr_t.

Perché vorremmo passare un valore nel template anziché nei parametri della funzione? Perché potremmo usarlo per effettuare validazioni (array bounds checking) o ottimizzazioni prima che il programma venga generato!

Ricorda la criptica notazione in stile C per ricevere una reference ad un array mantenendo viva l’informazione sulla sua lunghezza (che altrimenti decadrebbe in un puntatore perdendo la size): T (&arr)[N].

Possiamo sostituire sia la lunghezza N che il tipo T usando i template!

L’uso di static_assert per il controllo dell’accesso all’array in questo caso trasforma un potenziale catastrofico buffer overflow a runtime, in un banale errore rosso dell’editor durante la stesura del codice.

Esistono situazioni in cui il numero di argomenti che devi passare a una funzione template è ignoto a priori (ad esempio se stai programmando una tua versione alternativa di printf o funzioni che costruiscono oggetti).

Questi si chiamano Variadic Templates e utilizzano la sintassi dell’ellissi (...) chiamata Parameter Pack (Pacchetto di parametri).

// "Arguments" è un parameter pack type.
// "arguments" è il reale parameter pack instanziato.
template <typename T, typename... Arguments>
SimpleUniquePointer<T> make_simple_unique(Arguments... arguments) {
return SimpleUniquePointer<T>{ new T{ arguments... } };
}

L’espansione dei parameter pack è un meccanismo avanzato che il compilatore gestisce in background, permettendo al programmatore di passare da zero a decine di argomenti slegati senza dover codificare a mano tutte le possibili combinazioni.