0Pricing
C++ Academy · Lektion

Vollständige Spezialisierung

Templates für einen Typ anpassen

Vollständige Spezialisierung ist eine kostenlose C++ Academy-Lektion auf CoddyKit. Dies ist Lektion 1 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.

Zusammenfassung: Templates

Mit einem Template kann ein Stück Code für viele Typen funktionieren. Der Compiler erzeugt für jeden verwendeten Typ eine konkrete Version.

  • Die allgemeine Form verarbeitet jeden Typ.
  • Manchmal benötigt ein Typ eine spezielle Behandlung.
#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;
}

Was ist eine vollständige Spezialisierung?

Eine vollständige Spezialisierung stellt für genau einen bestimmten Typ eine vollständig separate Implementierung bereit und überschreibt damit das allgemeine Template ausschließlich für diesen Typ.

#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;
}

Die Syntax

Eine vollständige Spezialisierung beginnt mit leeren spitzen Klammern template <> und nennt den exakten Typ in der Spezialisierung.

#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;
}

Ein Klassentemplate spezialisieren

Vollständige Klassentemplates können spezialisiert werden, sodass ein Typ eigene Member und eigenes Verhalten erhält, die sich vom primären Template unterscheiden.

#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;
}

Warum spezialisieren?

Eine Spezialisierung behandelt Typen, die eine andere Logik benötigen, etwa const char*, für den ein Stringvergleich statt eines Zeigervergleichs erforderlich ist.

#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;
}

Ein einzelnes Member spezialisieren

Bei einem Klassentemplate können Sie für einen bestimmten Typ nur eine einzelne Memberfunktion spezialisieren und den übrigen Code wiederverwenden.

#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;
}

Die passendste Übereinstimmung gewinnt

Wenn eine vollständige Spezialisierung für den exakten Typ vorhanden ist, bevorzugt der Compiler sie immer gegenüber dem primären Template.

#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;
}

Die Spezialisierung muss auf das primäre Template folgen

Eine Spezialisierung muss deklariert werden, nachdem das primäre Template sichtbar ist. Andernfalls gibt es für den Compiler nichts zu spezialisieren.

#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;
}

std-Templates spezialisieren

Sie dürfen einige Templates der Standardbibliothek, etwa std::hash, für eigene Typen spezialisieren, damit diese mit Hash-Containern funktionieren.

#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;
}

Wertspezialisierung

Nicht-Typ-Templateparameter können auf bestimmte Werte spezialisiert werden, was für Tabellen zur Compilezeit nützlich ist.

#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;
}

Konsistentes Verhalten beibehalten

Eine Spezialisierung sollte denselben konzeptionellen Vertrag wie das primäre Template einhalten; nur die Implementierung ändert sich. Andernfalls werden Aufrufer überrascht.

#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;
}

Schnelltest

Testen Sie Ihr Verständnis der Syntax für vollständige Spezialisierungen.

Zusammenfassung

Sie haben die vollständige Spezialisierung kennengelernt:

  • Sie stellt eine eigene Implementierung für genau einen Typ bereit
  • Sie wird mit template <> und dem konkreten Typ geschrieben
  • Der Compiler bevorzugt immer eine exakte Spezialisierung
  • Sie funktioniert für Funktionen, Klassen, einzelne Member und bestimmte Werte

Als Nächstes sehen Sie sich die partielle Spezialisierung an, die auf Typmuster passt.

Häufig gestellte Fragen

Ist die Lektion „Vollständige Spezialisierung“ kostenlos?

Ja — der vollständige Text von „Vollständige Spezialisierung“ 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 „Vollständige Spezialisierung“?

Templates für einen Typ anpassen 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 1 von 4.

Wie lange dauert die Lektion „Vollständige Spezialisierung“?

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