Specializzazione completa
Personalizzare i template per un tipo
Specializzazione completa è una lezione C++ Academy gratuita su CoddyKit. Questa è la lezione 1 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.
Riepilogo: template
Un template permette a un frammento di codice di funzionare con molti tipi. Il compilatore genera una versione concreta per ogni tipo utilizzato.
- La forma generale gestisce ogni tipo.
- A volte un tipo richiede un trattamento speciale.
#include <iostream>
template <typename T>
T maxOf(T a, T b) { return a > b ? a : b; }
int main() {
std::cout << maxOf(3, 9) << ' ' << maxOf(2.5, 1.5) << '\n';
return 0;
}Che cos'è la specializzazione completa?
La specializzazione completa fornisce un'implementazione completamente separata per un tipo specifico, sostituendo il template generale solo per quel tipo.
#include <iostream>
template <typename T>
void describe(T) { std::cout << "some type\n"; }
template <>
void describe(int) { std::cout << "an int\n"; }
int main() {
describe(3.14);
describe(42);
return 0;
}La sintassi
Una specializzazione completa inizia con parentesi angolari vuote template <> e indica il tipo esatto nella specializzazione.
#include <iostream>
template <typename T>
struct TypeName { static const char* get() { return "unknown"; } };
template <>
struct TypeName<bool> { static const char* get() { return "bool"; } };
int main() {
std::cout << TypeName<double>::get() << '\n';
std::cout << TypeName<bool>::get() << '\n';
return 0;
}Specializzare un class template
È possibile specializzare interamente i class template, assegnando a un tipo membri e comportamenti propri, distinti da quelli del template primario.
#include <iostream>
template <typename T>
struct Storage {
T value;
void show() { std::cout << "value: " << value << '\n'; }
};
template <>
struct Storage<bool> {
bool value;
void show() { std::cout << (value ? "true" : "false") << '\n'; }
};
int main() {
Storage<int> s{5}; s.show();
Storage<bool> b{true}; b.show();
return 0;
}Perché specializzare?
La specializzazione gestisce i tipi che richiedono una logica diversa, ad esempio const char*, che richiede il confronto tra stringhe anziché il confronto tra puntatori.
#include <iostream>
#include <cstring>
template <typename T>
bool equal(T a, T b) { return a == b; }
template <>
bool equal(const char* a, const char* b) { return std::strcmp(a, b) == 0; }
int main() {
std::cout << std::boolalpha;
std::cout << equal(5, 5) << '\n';
std::cout << equal("hi", "hi") << '\n';
return 0;
}Specializzare un singolo membro
Per un class template è possibile specializzare una sola funzione membro per un determinato tipo, riutilizzando tutte le altre.
#include <iostream>
template <typename T>
struct Printer {
void print(T v) { std::cout << v << '\n'; }
};
template <>
void Printer<char>::print(char v) {
std::cout << "char: " << v << '\n';
}
int main() {
Printer<int>{}.print(7);
Printer<char>{}.print('A');
return 0;
}La corrispondenza prevale sulla generalità
Quando esiste una specializzazione completa per il tipo esatto, il compilatore la preferisce sempre al template primario.
#include <iostream>
template <typename T>
int rank() { return 0; }
template <>
int rank<double>() { return 99; }
int main() {
std::cout << rank<int>() << ' ' << rank<double>() << '\n';
return 0;
}La specializzazione deve seguire il template primario
Una specializzazione deve essere dichiarata dopo che il template primario è visibile; altrimenti il compilatore non ha nulla da specializzare.
#include <iostream>
template <typename T>
const char* kind() { return "generic"; }
template <>
const char* kind<float>() { return "float"; }
int main() {
std::cout << kind<int>() << ' ' << kind<float>() << '\n';
return 0;
}Specializzare i template std
È possibile specializzare alcuni template della libreria standard, come std::hash, per i propri tipi, così da poterli usare con i contenitori hash.
#include <iostream>
struct Point { int x, y; };
template <typename T>
struct Hasher { size_t operator()(const T&) { return 0; } };
template <>
struct Hasher<Point> {
size_t operator()(const Point& p) { return p.x * 31 + p.y; }
};
int main() {
Hasher<Point> h;
std::cout << h(Point{2, 3}) << '\n';
return 0;
}Specializzazione per valore
I parametri di template non di tipo possono essere specializzati in base a valori specifici, una soluzione utile per le tabelle generate a tempo di compilazione.
#include <iostream>
template <int N>
struct Fib { static const int value = Fib<N-1>::value + Fib<N-2>::value; };
template <>
struct Fib<0> { static const int value = 0; };
template <>
struct Fib<1> { static const int value = 1; };
int main() {
std::cout << Fib<10>::value << '\n';
return 0;
}Mantenere coerente il comportamento
Una specializzazione dovrebbe mantenere lo stesso contratto concettuale del template primario e modificare soltanto l'implementazione. In caso contrario, il codice chiamante può ottenere risultati inattesi.
#include <iostream>
template <typename T>
T zero() { return T{}; }
template <>
int zero<int>() { return 0; }
int main() {
std::cout << zero<int>() << ' ' << zero<double>() << '\n';
return 0;
}Verifica rapida
Verifichi la Sua comprensione della sintassi della specializzazione completa.
Riepilogo
Ha imparato a conoscere la specializzazione completa:
- fornisce un'implementazione dedicata per un solo tipo esatto
- si scrive con
template <>e il tipo concreto - il compilatore dà sempre la precedenza a una specializzazione esatta
- funziona per funzioni, classi, singoli membri e valori specifici
Successivamente, vedrà la specializzazione parziale, che corrisponde a pattern di tipi.
Domande Frequenti
La lezione «Specializzazione completa» è gratuita?
Sì — il testo completo di «Specializzazione completa» è 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 «Specializzazione completa»?
Personalizzare i template per un tipo 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 1 di 4.
Quanto tempo richiede la lezione «Specializzazione completa»?
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
- Specializzazione completa
- Specializzazione parziale
- SFINAE
- Pattern con enable_if