⚙️ C++20 Generic Programming

C++ 09: Function Templates & Class Templates

Schreibe typsicheren, wiederverwendbaren Code mit C++ Templates: Funktions-Templates, Template-Klassen, Non-Type Template Parameters (NTTP) und explizite Spezialisierung.

📐 1. Funktions-Templates (template<typename T>)

Templates ermöglichen es, Algorithmen unabhängig von konkreten Datentypen zu formulieren. Zur Compile-Zeit generiert der C++-Compiler (Monomorphisierung) für jeden verwendeten Typ eine optimierte Maschinenbauform:

#include <iostream>
#include <string>

// Generische Minimum-Funktion
template <typename T>
T min_value(T a, T b) {
    return (a < b) ? a : b;
}

// Mehrere Template-Parameter
template <typename T, typename U>
auto add_heterogeneous(T a, U b) -> decltype(a + b) {
    return a + b;
}

int main() {
    std::cout << min_value(10, 20) << "\n";          // T = int
    std::cout << min_value(3.14, 2.71) << "\n";      // T = double
    std::cout << min_value<std::string>("Alpha", "Beta") << "\n"; // Explizit
}
🏢 Didaktische Analogie: Der 3D-Drucker-Gussplan

Ein Template ist kein fertiges Bauteil, sondern eine Gussform (Blaupause). Wenn du min_value(5, 10) aufrufst, gießt der Compiler eine int-Version. Rufst du min_value(2.5, 4.1) auf, gießt er eine double-Version. Es gibt keinen Runtime-Overhead (Zero-Cost Abstraction)!

📦 2. Klassen-Templates & Non-Type Template Parameters (NTTP)

Klassen können generisch über Datentypen und über compile-zeitliche Konstanten (wie Array-Größen) parametrisiert werden:

#include <cstddef>
#include <stdexcept>

// T = Datentyp, Size = Compile-Zeit Konstante (NTTP)
template <typename T, std::size_t Size>
class StaticStack {
private:
    T data_[Size];
    std::size_t top_{0};

public:
    void push(const T& item) {
        if (top_ >= Size) throw std::overflow_error("Stack Overflow");
        data_[top_++] = item;
    }

    T pop() {
        if (top_ == 0) throw std::underflow_error("Stack Underflow");
        return data_[--top_];
    }

    [[nodiscard]] std::size_t capacity() const { return Size; }
    [[nodiscard]] std::size_t size() const { return top_; }
};

🔍 3. Explizite Template-Spezialisierung

Manchmal erfordern spezifische Datentypen (z.B. bool oder const char*) eine spezialisierte Behandlung:

// Primäres Template
template <typename T>
struct TypeFormatter {
    static std::string format(const T& val) {
        return "Generic: " + std::to_string(val);
    }
};

// Vollständige Spezialisierung für std::string
template <>
struct TypeFormatter<std::string> {
    static std::string format(const std::string& val) {
        return "String: \"" + val + "\"";
    }
};

// Spezialisierung für bool
template <>
struct TypeFormatter<bool> {
    static std::string format(const bool& val) {
        return val ? "Bool: TRUE" : "Bool: FALSE";
    }
};

📑 4. Cheat-Sheet: C++ Template Konzepte

Konstrukt Syntax-Beispiel Bedeutung & Verwendungszweck
template<typename T> T square(T x) { return x * x; } Funktions-Template für beliebige numerische Typen
Class Template template<typename T> class Buffer; Generischer Container oder Wrapper
NTTP (Non-Type) template<typename T, size_t N> Größen oder Konstanten fest zur Compile-Zeit binden
Template Specialization template<> struct Formatter<bool> Sonderlogik für bestimmte Typen definieren
Type Alias (using) template<typename T> using Vec = std::vector<T>; Lesbare Alias-Namen für komplexe Template-Typen

🧠 Diagnostischer Selbst-Check

Überprüfe dein Verständnis zu Speichersicherheit, Syntax und Systems-Design mit gezieltem Feedback:

🎯 Aufgaben & Checkliste in aufgabe.cpp

💡 C++20 Pro-Tipp: Header-Only Templates

Weil der Compiler den Quellcode der Templates kennen muss, um konkrete Typ-Instanziierungen zu kompilieren, werden Template-Definitionen in C++ üblicherweise komplett in Header-Dateien (.hpp / .h) platziert!

💻 In Web-IDE öffnen → Weiter zu C++ 10 →