Schémas avec enable_if
Contraindre les modèles selon l’approche classique
Schémas avec enable_if est une leçon C++ Academy gratuite sur CoddyKit. Ceci est la leçon 4 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.
Qu’est-ce que enable_if ?
std::enable_if est un petit trait qui définit conditionnellement un membre type. Lorsque sa condition est vraie, le type existe ; lorsqu’elle est fausse, le modèle environnant est retiré par SFINAE.
- Il se trouve dans
<type_traits>. - C’est l’outil classique pour restreindre les modèles.
#include <iostream>
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
doubleIt(T v) { return v * 2; }
int main() {
std::cout << doubleIt(21) << '\n';
return 0;
}Fonctionnement
enable_if<Cond, T>::type est égal à T uniquement lorsque Cond est vrai. Si Cond est faux, aucun membre type n’existe et la substitution échoue.
#include <iostream>
#include <type_traits>
int main() {
std::cout << std::boolalpha;
std::cout << std::is_same<std::enable_if<true, int>::type, int>::value << '\n';
return 0;
}enable_if dans le type de retour
Le placement le plus courant est le type de retour. La fonction n’existe que lorsque la condition est satisfaite.
#include <iostream>
#include <type_traits>
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, T>::type
half(T v) { return v / 2; }
int main() {
std::cout << half(5.0) << '\n';
return 0;
}enable_if comme paramètre de modèle
Une autre forme courante place enable_if dans un paramètre de modèle par défaut, ce qui laisse le type de retour propre.
#include <iostream>
#include <type_traits>
template <typename T, typename = typename std::enable_if<std::is_integral<T>::value>::type>
T triple(T v) { return v * 3; }
int main() {
std::cout << triple(4) << '\n';
return 0;
}Raccourci enable_if_t
C++14 a ajouté l’alias std::enable_if_t<Cond, T>, qui vous permet d’éviter la syntaxe typename ...::type superflue.
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_integral<T>::value, T>
negate(T v) { return -v; }
int main() {
std::cout << negate(8) << '\n';
return 0;
}Associer deux surcharges
Définissez des conditions complémentaires afin qu’exactement une surcharge soit valide pour chaque type, sans ambiguïté.
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_integral<T>::value, const char*>
category() { return "integer"; }
template <typename T>
std::enable_if_t<!std::is_integral<T>::value, const char*>
category() { return "non-integer"; }
int main() {
std::cout << category<int>() << ' ' << category<double>() << '\n';
return 0;
}Combiner des conditions
Utilisez des opérateurs logiques sur les valeurs des traits pour exprimer des contraintes plus riches, comme « entier et signé ».
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_integral<T>::value && std::is_signed<T>::value, T>
magnitude(T v) { return v < 0 ? -v : v; }
int main() {
std::cout << magnitude(-12) << '\n';
return 0;
}Restreindre un constructeur
Vous pouvez placer enable_if sur le paramètre de modèle d’un constructeur afin de ne l’autoriser que pour les types compatibles.
#include <iostream>
#include <type_traits>
struct Wrapper {
int value;
template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>>
Wrapper(T v) : value(static_cast<int>(v)) {}
};
int main() {
Wrapper w(42);
std::cout << w.value << '\n';
return 0;
}Piège des arguments de modèle par défaut
Deux surcharges qui ne diffèrent que par un paramètre de modèle enable_if par défaut sont considérées comme des redéfinitions. Donnez-leur des formes différentes, par exemple en plaçant une condition sur le type de retour.
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_integral<T>::value, void>
printKind() { std::cout << "int\n"; }
template <typename T>
std::enable_if_t<std::is_floating_point<T>::value, void>
printKind() { std::cout << "float\n"; }
int main() {
printKind<int>();
printKind<double>();
return 0;
}Comparaison avec les concepts
En C++20, les concepts remplacent la plupart des utilisations de enable_if avec une syntaxe beaucoup plus claire, mais enable_if reste essentiel pour le code antérieur à C++20 et certains cas particuliers.
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_arithmetic<T>::value, T>
square(T v) { return v * v; }
int main() {
std::cout << square(6) << ' ' << square(1.5) << '\n';
return 0;
}Un exemple complet
Combinez tous les éléments : une famille de fonctions qui formate différemment les entiers et les nombres flottants, avec une sélection effectuée à la compilation.
#include <iostream>
#include <type_traits>
template <typename T>
std::enable_if_t<std::is_integral<T>::value, void>
format(T v) { std::cout << "int[" << v << "]\n"; }
template <typename T>
std::enable_if_t<std::is_floating_point<T>::value, void>
format(T v) { std::cout << "float(" << v << ")\n"; }
int main() {
format(10);
format(3.5);
return 0;
}Vérification rapide
Vérifiez votre compréhension de enable_if.
Récapitulatif
Vous avez découvert les motifs classiques utilisant enable_if :
- il définit
::typeuniquement lorsque la condition est vraie, ce qui permet SFINAE - il se place dans le type de retour ou dans un paramètre de modèle par défaut
- utilisez l’alias
enable_if_tet combinez les traits avec des opérateurs logiques - les concepts le remplacent en C++20, mais il reste largement utilisé
Le cours sur la spécialisation des modèles et SFINAE est maintenant terminé.
Apprends C++ avec un tuteur IA — gratuit
Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.
- Cours
- 51
- Leçons
- 203
Questions Fréquemment Posées
La leçon « Schémas avec enable_if » est-elle gratuite ?
Oui — le texte complet de « Schémas avec enable_if » 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 « Schémas avec enable_if » ?
Contraindre les modèles selon l’approche classique 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 4 sur 4.
Combien de temps prend la leçon « Schémas avec enable_if » ?
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