Generics in C++: Templates, warum sie benötigt werden und wie man sie verwendet

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten
```html

Einleitung: Was sind Generics (Templates) in C++ und wozu braucht man sie?



In der Welt der C++-Programmierung ist eines der Schlüsselkonzepte, das es ermöglicht, flexiblen, wiederverwendbaren und typsicheren Code zu schreiben, Templates. Sie werden oft als "Generics" bezeichnet, analog zu anderen Sprachen wie Java oder C#, obwohl dieses Konzept in C++ deutlich mächtiger und tiefergehend ist.



Stellen Sie sich vor, Sie müssten eine Funktion schreiben, um das maximale Element in einem Array zu finden. Für ganze Zahlen (int) wäre es eine Funktion, für Gleitkommazahlen (double) eine andere, für Zeichenketten (std::string) eine dritte. Ohne Templates müssten Sie den Code duplizieren, was zu Fehlern führt und die Wartung erschwert.



Generics (Templates) lösen dieses Problem. Sie ermöglichen es, Code zu schreiben, der mit jedem Datentyp arbeitet, ohne dabei die Leistung zu opfern (im Gegensatz zu virtuellen Funktionen oder void*). Templates sind das Fundament der C++-Standardbibliothek (STL): Container (std::vector, std::map), Algorithmen (std::sort, std::find) und intelligente Zeiger (std::shared_ptr) – sie alle sind mit Hilfe von Templates implementiert.



In diesem Artikel werden wir uns ansehen, was Templates in C++ sind, wie man sie richtig deklariert und verwendet, und praktische Beispiele betrachten.



Hauptteil: Wie man Generics (Templates) in C++ verwendet



1. Funktionstemplates (Function Templates)



Der einfachste Weg, mit Generics zu beginnen, ist die Erstellung eines Funktionstemplates. Anstatt mehrere überladene Versionen zu schreiben, schreiben Sie eine, die durch einen Typ parametrisiert ist.



Syntax:

template <typename T>T max(T a, T b) {    return (a > b) ? a : b;}


Das Schlüsselwort template teilt dem Compiler mit, dass es sich um ein Template handelt. <typename T> deklariert den Typparameter T. Sie können class anstelle von typename verwenden – es gibt keinen Unterschied.



Anwendungsbeispiel:

#include <iostream>#include <string>

template <typename T>T max(T a, T b) { return (a > b) ? a : b;}

int main() { std::cout << max(10, 20) << std::endl; // int: 20 std::cout << max(3.14, 2.71) << std::endl; // double: 3.14 std::cout << max(std::string("C++"), std::string("Python")) << std::endl; // string: Python return 0;}


Wichtig: Der Compiler generiert für jeden verwendeten Typ eine separate Version der Funktion. Dies wird als Template-Instantiierung bezeichnet. Dadurch wird maximale Leistung erzielt – es gibt keinen Overhead durch virtuelle Aufrufe.



Mehrere Typparameter:

template <typename T1, typename T2>void printPair(T1 a, T2 b) {    std::cout << "(" << a << ", " << b << ")" << std::endl;}// printPair(1, "hello"); // Gibt aus: (1, hello)


2. Klassentemplates (Class Templates)



Klassentemplates ermöglichen die Erstellung generischer Datenstrukturen. Ein klassisches Beispiel ist std::vector<T>. Sie können Ihre eigene Template-Klasse erstellen, zum Beispiel einen einfachen Stack:



template <typename T>class Stack {private:    T* data;    size_t size;    size_t capacity;public:    Stack(size_t cap = 10) : size(0), capacity(cap) {        data = new T[capacity];    }    ~Stack() { delete[] data; }

void push(const T& value) { if (size < capacity) { data[size++] = value; } }

T pop() { if (size > 0) { return data[--size]; } throw std::out_of_range("Stack is empty"); }

bool isEmpty() const { return ```

Blogs

Buchempfehlungen