0Pricing
C++ Academy · Lektion

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 ::type nur 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_t und 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

  1. Vollständige Spezialisierung
  2. Partielle Spezialisierung
  3. SFINAE
  4. enable_if-Muster
← Zurück zu C++ Academy