Skip to content

Introduzione ai Template

Mentre il polimorfismo a runtime si basa su Interfacce e si risolve mentre il programma è in esecuzione, il polimorfismo a tempo di compilazione (Compile-Time Polymorphism) in C++ si ottiene attraverso i Template.

Un template (modello) è una classe o una funzione dotata di parametri di template. Questi parametri agiscono da segnaposto (placeholder) per tipi reali che verranno specificati in seguito. Quando il compilatore incontra l’uso di un template con dei tipi specifici, genera letteralmente da zero il codice sorgente C++ di una nuova classe o funzione su misura per quei tipi. Questo processo si chiama Istanziazione del Template.

L’idea fondamentale è: invece di fare un copia-e-incolla noioso del codice per supportare int, float e double, scrivi un singolo template. Il compilatore farà il copia-e-incolla per te dietro le quinte!

Si dichiara un template inserendo il prefisso template <typename T> subito prima della dichiarazione. La parola chiave typename e la parola chiave class all’interno delle parentesi angolari < > significano esattamente la stessa cosa per ragioni storiche, ma noi useremo typename.

template <typename X, typename Y, typename Z>
struct MyTemplateClass {
X foo(Y& input);
private:
Z* member;
};

All’interno della struttura, puoi usare X, Y e Z come se fossero tipi veri e propri (come int o char).

Lo stesso principio si applica alle funzioni. Puoi usarle per costruire algoritmi generici.

Quando scrivi multiply<int>(5, 10), il compilatore va fisicamente a creare una funzione nascosta simile a int multiply_int(int a, int b) { return a * b; } e la compila. Questa operazione garantisce Zero Overhead a runtime: l’esecuzione è veloce tanto quanto l’aver scritto la funzione esplicitamente a mano!