enable_if-Muster
Templates auf klassische Weise einschränken
enable_if-Muster ist eine kostenlose C++ Academy-Lektion auf CoddyKit. Dies ist Lektion 4 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des C++ Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der C++ Academy-Kurs umfasst insgesamt 4 Lektionen.
Was ist enable_if?
std::enable_if ist ein kleines Typmerkmal, das ein type-Member bedingt definiert. Wenn die Bedingung wahr ist, ist der Typ vorhanden; wenn sie falsch ist, wird das umgebende Template durch SFINAE entfernt.
- Es befindet sich in
<type_traits>. - Es ist das klassische Werkzeug zum Einschränken von Templates.
#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;
}So funktioniert es
enable_if<Cond, T>::type ist nur dann T, wenn Cond wahr ist. Andernfalls gibt es kein type-Member, sodass die Substitution fehlschlägt.
#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 im Rückgabetyp
Am häufigsten wird enable_if im Rückgabetyp platziert. Die Funktion ist nur dann vorhanden, wenn die Bedingung erfüllt ist.
#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 als Templateparameter
Ein anderes Idiom platziert enable_if in einem Templateparameter mit Standardwert, sodass der Rückgabetyp übersichtlich bleibt.
#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;
}Kurzform enable_if_t
C++14 fügte das Alias std::enable_if_t<Cond, T> hinzu, sodass Sie die umständliche Schreibweise typename ...::type vermeiden können.
#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;
}Zwei Überladungen kombinieren
Stellen Sie komplementäre Bedingungen bereit, sodass für jeden Typ genau eine Überladung gültig ist und keine Mehrdeutigkeit entsteht.
#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;
}Bedingungen kombinieren
Verwenden Sie logische Operatoren auf den Werten von Typmerkmalen, um komplexere Einschränkungen auszudrücken, etwa "integral und signed".
#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;
}Einen Konstruktor einschränken
Sie können enable_if auf den Templateparameter eines Konstruktors anwenden, damit dieser nur für kompatible Typen zugelassen wird.
#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;
}Fallstrick bei Templateargumenten mit Standardwert
Zwei Überladungen, die sich nur durch einen Templateparameter mit Standardwert und enable_if unterscheiden, werden als Neudefinitionen betrachtet. Geben Sie ihnen unterschiedliche Formen, indem Sie beispielsweise eine der Bedingungen auf den Rückgabetyp anwenden.
#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;
}Vergleich mit Concepts
Die Concepts aus C++20 ersetzen den Großteil der Verwendung von enable_if durch eine deutlich klarere Syntax. Dennoch bleibt enable_if für Code vor C++20 und einige Sonderfälle unverzichtbar.
#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;
}Ein vollständiges Beispiel
Führen Sie alles zusammen: eine Funktionsfamilie, die Ganzzahlen und Gleitkommazahlen unterschiedlich formatiert und zur Compilezeit ausgewählt wird.
#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;
}Schnelltest
Testen Sie Ihr Verständnis von enable_if.
Zusammenfassung
Sie haben die klassischen enable_if-Muster kennengelernt:
- Es definiert
::typenur dann, wenn die Bedingung wahr ist, und ermöglicht dadurch SFINAE - Es wird im Rückgabetyp oder in einem Templateparameter mit Standardwert platziert
- Verwenden Sie das Alias
enable_if_tund kombinieren Sie Typmerkmale mit logischen Operatoren - Concepts lösen es in C++20 ab, dennoch wird es weiterhin häufig verwendet
Damit ist der Kurs zu Template-Spezialisierung und SFINAE abgeschlossen.
Häufig gestellte Fragen
Ist die Lektion „enable_if-Muster“ kostenlos?
Ja — der vollständige Text von „enable_if-Muster“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des C++ Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der C++ Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „enable_if-Muster“?
Templates auf klassische Weise einschränken Du übst C++ Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um C++ Academy zu starten?
Keine Vorkenntnisse erforderlich. C++ Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 4 von 4.
Wie lange dauert die Lektion „enable_if-Muster“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser C++ Academy-Lektion Code schreiben und ausführen?
Ja. Jede C++ Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Vollständige Spezialisierung
- Partielle Spezialisierung
- SFINAE
- enable_if-Muster