Sostieni AppuntiFacili con una piccola donazione su PayPal
Dona con PayPalI template in C++ sono uno strumento fondamentale per scrivere codice generico, riutilizzabile e flessibile.
Permettono di definire funzioni e classi che operano su tipi diversi, senza dover riscrivere lo stesso codice per ogni tipo di dato.

INFO
Definizione: Un template è un modello che permette al compilatore di generare automaticamente versioni specifiche di funzioni o classi per i tipi richiesti.
int, double, string).Durante la compilazione:
Esempio:
somma(3, 4); // genera somma<int>(int, int)
somma(2.5, 1.5); // genera somma<double>(double, double)
Un function template permette di scrivere funzioni che lavorano con tipi diversi.
#include <iostream>
using namespace std;
template <typename T>
T somma(T a, T b) {
return a + b;
}
int main() {
cout << somma(3, 7) << endl; // int
cout << somma(2.5, 3.5) << endl; // double
return 0;
}
template <typename T> definisce un parametro di tipo generico.TIP
Possibile usare anche template <class T>, è equivalente.
Un class template consente di creare strutture dati generiche.
#include <iostream>
using namespace std;
template <typename T>
class Scatola {
private:
T contenuto;
public:
Scatola(T c) : contenuto(c) {}
T get() { return contenuto; }
};
int main() {
Scatola<int> s1(42);
Scatola<string> s2("Ciao Template");
cout << s1.get() << endl;
cout << s2.get() << endl;
/*
Output:
42
Ciao Template
*/
}
INFO
Ogni volta che si istanzia Scatola<T>, il compilatore crea una versione specifica per il tipo richiesto.
Vantaggi dei class template:
vector, map, set).Puoi definire più parametri di tipo:
#include <iostream>
using namespace std;
template <typename T, typename U>
void stampa(T a, U b) {
cout << a << " e " << b << endl;
}
int main() {
stampa(10, 3.14);
stampa("C++", 2025);
/*
Output:
10 e 3.14
C++ e 2025
*/
}
È possibile definire tipi di default per i parametri template:
template <typename T = int>
class Valore {
T dato;
public:
Valore(T d) : dato(d) {}
void mostra() { std::cout << dato << std::endl; }
};
int main() {
Valore<> v1(5); // Usa int di default
Valore<double> v2(3.14);
v1.mostra();
v2.mostra();
}
La specializzazione permette di personalizzare il comportamento per un tipo specifico.
#include <iostream>
using namespace std;
template <typename T>
void mostra(T x) {
cout << "Generico: " << x << endl;
}
// Specializzazione per string
template <>
void mostra<string>(string x) {
cout << "Stringa: " << x << endl;
}
int main() {
mostra(10);
mostra(string("Ciao"));
/*
Output:
Generico: 10
Stringa: Ciao
*/
}
Una classe template può avere metodi template:
#include <iostream>
using namespace std;
template <typename T>
class Wrapper {
public:
T valore;
Wrapper(T v) : valore(v) {}
template <typename U>
void combina(U altro) {
cout << valore + altro << endl;
}
};
int main() {
Wrapper<int> w(10);
w.combina(5); // 15
w.combina(2.5); // 12.5
}
Con C++17 e C++20, i template sono diventati ancora più potenti.
#include <iostream>
#include <vector>
using namespace std;
template <template <typename, typename> class Container, typename T>
class Gestore {
Container<T, allocator<T>> dati;
public:
void aggiungi(T val) { dati.push_back(val); }
void mostra() {
for (auto& el : dati) cout << el << " ";
cout << endl;
}
};
int main() {
Gestore<vector, int> g;
g.aggiungi(1);
g.aggiungi(2);
g.mostra();
}
I concepts permettono di specificare vincoli sui tipi nei template:
#include <concepts>
#include <iostream>
using namespace std;
template <std::integral T>
T quadrato(T x) {
return x * x;
}
int main() {
cout << quadrato(5) << endl; // OK
// cout << quadrato(3.14); // Errore: non è integrale
}
TIP
I concepts rendono il codice più leggibile e i messaggi d’errore più chiari!
#include <iostream>
#include <vector>
using namespace std;
template <typename T>
class Stack {
vector<T> elementi;
public:
void push(T val) { elementi.push_back(val); }
void pop() { if(!elementi.empty()) elementi.pop_back(); }
T top() { return elementi.back(); }
bool vuoto() { return elementi.empty(); }
};
int main() {
Stack<int> s;
s.push(10);
s.push(20);
cout << s.top() << endl; // 20
s.pop();
cout << s.top() << endl; // 10
}
maxGenericoCrea una funzione template maxGenerico che:
T,Esempio d’uso:
cout << maxGenerico(10, 25) << endl; // 25
cout << maxGenerico(3.5, 2.1) << endl; // 3.5
cout << maxGenerico(string("Ciao"), string("Mondo")) << endl; // Mondo
Crea una classe template Coppia<T1, T2> che rappresenti una coppia di valori (di tipi potenzialmente diversi).
La classe deve:
mostra() che stampi i due valori,scambia() che inverta i valori (solo se T1 e T2 sono uguali).Esempio d’uso:
Coppia<int, string> c1(5, "elementi");
c1.mostra(); // (5, elementi)
Coppia<int, int> c2(10, 20);
c2.scambia();
c2.mostra(); // (20, 10)
Crea una classe template Stack<T> che funzioni come una pila (LIFO).
La classe deve fornire:
push(T) per aggiungere un elemento,pop() per rimuovere l’ultimo elemento,top() per ottenere l’ultimo elemento inserito,vuoto() che restituisce true se lo stack è vuoto.Esempio d’uso:
Stack<int> s;
s.push(10);
s.push(20);
cout << s.top() << endl; // 20
s.pop();
cout << s.top() << endl; // 10
1) Cosa permette di fare un template in C++?
2) Qual è la sintassi corretta per dichiarare un template di funzione?
3) Cosa fa la specializzazione di un template?
4) Cosa restituisce find() in una std::map o std::set?
5) Qual è lo scopo dei 'concepts' in C++20?