Spécialisation complète
Personnaliser les modèles pour un type
Spécialisation complète est une leçon C++ Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage C++ Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours C++ Academy comprend 4 leçons au total.
Récapitulatif : modèles
Un modèle permet à un même fragment de code de fonctionner avec de nombreux types. Le compilateur génère une version concrète pour chaque type utilisé.
- La forme générale prend en charge tous les types.
- Parfois, un type nécessite un traitement spécial.
#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;
}Qu'est-ce qu'une spécialisation complète ?
La spécialisation complète fournit une implémentation entièrement distincte pour un type précis, en remplaçant le modèle général uniquement pour ce type.
#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 syntaxe
Une spécialisation complète commence par des chevrons vides template <> et indique le type exact dans la spécialisation.
#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;
}Spécialiser un modèle de classe
Des modèles de classe entiers peuvent être spécialisés, ce qui donne à un type ses propres membres et son propre comportement, distincts de ceux du modèle principal.
#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;
}Pourquoi spécialiser ?
La spécialisation prend en charge les types qui nécessitent une logique différente, par exemple const char*, qui nécessite une comparaison de chaînes plutôt qu'une comparaison de pointeurs.
#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;
}Spécialiser un seul membre
Pour un modèle de classe, vous pouvez spécialiser une seule fonction membre pour un type donné tout en réutilisant le reste.
#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 correspondance l'emporte sur le général
Lorsqu'une spécialisation complète existe pour le type exact, le compilateur la préfère toujours au modèle principal.
#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 spécialisation doit suivre le modèle principal
Une spécialisation doit être déclarée après que le modèle principal est devenu visible ; sinon, le compilateur n'a rien à spécialiser.
#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;
}Spécialiser des modèles de la bibliothèque standard
Vous pouvez spécialiser certains modèles de la bibliothèque standard, comme std::hash, pour vos propres types afin qu'ils fonctionnent avec des conteneurs hachés.
#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;
}Spécialisation de valeur
Les paramètres de modèle non typés peuvent être spécialisés pour des valeurs précises, ce qui est utile pour les tables produites à la compilation.
#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;
}Conserver un comportement cohérent
Une spécialisation doit conserver le même contrat conceptuel que le modèle principal ; seule l’implémentation change. Sinon, le code appelant risque d’être surpris.
#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;
}Vérification rapide
Vérifiez votre compréhension de la syntaxe de spécialisation complète.
Récapitulatif
Vous avez découvert la spécialisation complète :
- elle fournit une implémentation dédiée pour un type précis
- elle s’écrit avec
template <>et le type concret - le compilateur privilégie toujours une spécialisation exacte
- elle fonctionne pour les fonctions, les classes, les membres individuels et les valeurs précises
Vous allez maintenant découvrir la spécialisation partielle, qui correspond à des motifs de types.
Questions Fréquemment Posées
La leçon « Spécialisation complète » est-elle gratuite ?
Oui — le texte complet de « Spécialisation complète » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours C++ Academy, passe à CoddyKit PRO. Le cours C++ Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Spécialisation complète » ?
Personnaliser les modèles pour un type Tu pratiques C++ Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer C++ Academy ?
Aucune expérience préalable n'est requise. C++ Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.
Combien de temps prend la leçon « Spécialisation complète » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon C++ Academy ?
Oui. Chaque leçon C++ Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Spécialisation complète
- Spécialisation partielle
- SFINAE
- Schémas avec enable_if