kennen:schablonen
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
— | kennen:schablonen [2020-07-27 09:56] (aktuell) – angelegt - Externe Bearbeitung 127.0.0.1 | ||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
+ | ====== Schablonen ====== | ||
+ | > There' | ||
+ | >> | ||
+ | |||
+ | Schablonen (engl. [[.: | ||
+ | lassen Typen oder ganzzahlige Konstanten bis zur Nutzung der Schablone offen. | ||
+ | Sowohl [[# | ||
+ | als auch [[# | ||
+ | können als Schablonen definiert werden. | ||
+ | |||
+ | ===== Funktionsschablonen ===== | ||
+ | ==== Definition ==== | ||
+ | Funktionsschablonen sind nur bis auf die in der Schablonenparameterliste | ||
+ | angegebenen Typen oder Konstanten festgelegt. | ||
+ | Frei wählbare Typnamen werden in der Schablonenparameterliste | ||
+ | durch | ||
+ | [[.: | ||
+ | markiert. | ||
+ | |||
+ | Syntax: | ||
+ | > '' | ||
+ | > Funktionsdefinition | ||
+ | <code cpp> | ||
+ | template <class T, int faktor> | ||
+ | T vielfaches(T x) | ||
+ | { | ||
+ | return faktor*x; | ||
+ | } | ||
+ | |||
+ | template <class T> | ||
+ | T minimum(T const& x, T const& y) | ||
+ | { | ||
+ | return x<y ? x : y; | ||
+ | } | ||
+ | </ | ||
+ | ==== Aufruf ==== | ||
+ | Beim Übersetzen des Funktionsaufrufs wird bestimmt, | ||
+ | welcher konkrete Typ oder welcher Konstantenwert in die Schablone eingesetzt wird. | ||
+ | Der Quelltext der Schablone muss hier bekannt sein, | ||
+ | da jetzt eine konkrete Funktion aus der Schablone erzeugt wird. | ||
+ | |||
+ | Syntax: | ||
+ | > Funktionsname''<'' | ||
+ | <code cpp> | ||
+ | float x = vielfaches< | ||
+ | int i = minimum(3, 5); | ||
+ | double d = minimum(2.718, | ||
+ | float f = minimum< | ||
+ | </ | ||
+ | Die Typangabe ''< | ||
+ | erzwingt die Nutzung einer bestimmten Funktion. | ||
+ | Ohne diese Angabe wäre keine eindeutige Typzuordnung möglich. | ||
+ | Ist der konkrete Typ aus den Funktionsparametern eindeutig ableitbar, | ||
+ | brauchen beim Aufruf keine Schablonenargumente angegeben werden. | ||
+ | |||
+ | Eine gleichnamige Funktion mit konkreten Parametertypen (Spezialisierung) | ||
+ | hat Vorrang vor der Schablone. | ||
+ | |||
+ | ==== Parameter packs ==== | ||
+ | [[begriffe# | ||
+ | Diese können durch Rekursion aufgelöst werden: | ||
+ | <code cpp> | ||
+ | void writeln() | ||
+ | { | ||
+ | std::cout << ' | ||
+ | } | ||
+ | |||
+ | template< | ||
+ | void writeln(T t, Types... args) | ||
+ | { | ||
+ | std::cout << t; | ||
+ | writeln(args...) | ||
+ | } | ||
+ | </ | ||
+ | So lässt sich eine Funktion mit variabler Anzahl von Parametern nutzen: | ||
+ | <code cpp> | ||
+ | writeln(); | ||
+ | writeln(" | ||
+ | writeln(" | ||
+ | </ | ||
+ | ==== Faltausdrücke ==== | ||
+ | |||
+ | Ab [[begriffe# | ||
+ | dies eleganter: | ||
+ | <code cpp> | ||
+ | template< | ||
+ | void writeln(Types... args) | ||
+ | { | ||
+ | (std::cout << ... << args) << ' | ||
+ | } | ||
+ | </ | ||
+ | Links-/ | ||
+ | | | einstellig | zweistellig | wird aufgelöst als | | ||
+ | | Links-Faltung | ||
+ | | Rechts-Faltung | '' | ||
+ | |||
+ | ==== auto-Parameter ==== | ||
+ | <code cpp> | ||
+ | auto add(auto x, auto y) { return x+y; } | ||
+ | </ | ||
+ | ist ab [[begriffe# | ||
+ | <code cpp> | ||
+ | template < | ||
+ | auto add(X x, Y y) { return x+y; } | ||
+ | </ | ||
+ | |||
+ | ===== Klassenschablonen ===== | ||
+ | ==== Definition ==== | ||
+ | Klassenentwürfe, | ||
+ | Methodenparametern oder Rückgabewerten unterscheiden, | ||
+ | Typnamen werden in der Schablonenparameterliste | ||
+ | durch | ||
+ | [[.: | ||
+ | markiert. | ||
+ | |||
+ | Syntax: | ||
+ | > '' | ||
+ | > Klassendefinition | ||
+ | <code cpp> | ||
+ | template <class T, int size> | ||
+ | class Stack | ||
+ | { | ||
+ | public: | ||
+ | Stack(); | ||
+ | void push(T const& x); | ||
+ | T pop(); | ||
+ | bool is_empty() const; | ||
+ | bool is_full() | ||
+ | private: | ||
+ | T data[size]; | ||
+ | int anzahl; | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | ==== Methoden ==== | ||
+ | Außerhalb der Klassenschablone definierte Methoden werden wie ihre Klasse mit | ||
+ | '' | ||
+ | Hinter dem Klassennamen sind in spitzen Klammern | ||
+ | die Namen aus der Schablonenparameterliste aufzuführen. | ||
+ | |||
+ | <code cpp> | ||
+ | template <class T, int size> | ||
+ | int Stack<T, size>:: | ||
+ | { | ||
+ | return anzahl==size; | ||
+ | } | ||
+ | </ | ||
+ | Spezialisierungen erlauben Sonderverhalten für bestimmte konkrete Klassen. | ||
+ | |||
+ | <code cpp> | ||
+ | template <> | ||
+ | int Stack< | ||
+ | { | ||
+ | if (anzahl != size) return false; | ||
+ | std::cerr << ' | ||
+ | return true; | ||
+ | } | ||
+ | </ | ||
+ | ==== Konkretisierung ==== | ||
+ | Klassenschablonen werden durch | ||
+ | [[.: | ||
+ | [[.: | ||
+ | oder Variablen-Vereinbarungen konkretisiert. | ||
+ | Der Quelltext der Schablonenmethoden muss bei der Konkretisierung offenliegen. | ||
+ | Hinter dem Klassennamen sind konkrete Typen bzw. Konstanten | ||
+ | als Schablonenargumente in spitzen Klammern anzugeben. | ||
+ | |||
+ | Syntax: | ||
+ | > Klassenname''<'' | ||
+ | <code cpp> | ||
+ | // typedef Stack< | ||
+ | using IntegerStack = Stack< | ||
+ | Stack< | ||
+ | </ | ||
+ | |||
+ | ===== Beschränkungen ===== | ||
+ | Seit [[kennen: | ||
+ | eingeschränkt werden. | ||
kennen/schablonen.txt · Zuletzt geändert: 2020-07-27 09:56 von 127.0.0.1