namespace cpp {}

C++ lernen, kennen, anwenden

Benutzer-Werkzeuge

Webseiten-Werkzeuge


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's more to templates than is shown here.
 +>>---  Scott D. Meyers [Effective C++, item 49]
 +
 +Schablonen (engl. [[.:keywords#template]]) 
 +lassen Typen oder ganzzahlige Konstanten bis zur Nutzung der Schablone offen.
 +Sowohl [[#Funktionsschablonen|Funktionen]]
 +als auch [[#Klassenschablonen|Klassen]]
 +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
 +[[.:keywords#class]] oder [[.:keywords#typename]]
 +markiert.
 +
 +Syntax:
 +>  ''template <'' Schablonenparameterliste ''>''
 +>  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;
 +}
 +</code>
 +==== 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''<'' Schablonenargumentliste ''> ('' Funktionsargumentliste  '')''
 +<code cpp>
 +float  x = vielfaches<float,3>(5);  // 15
 +int    i = minimum(3, 5);
 +double d = minimum(2.718, 3.14);
 +float  f = minimum<float>(2.718, 3); 
 +</code>
 +Die Typangabe ''<float>'' beim letzten Funktionsaufuf 
 +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#C++11]] erlaubt die Angabe einer unbestimmten Anzahl von Schablonenparametern (parameter pack) mittels einer Ellipse ''%%...%%''
 +Diese können durch Rekursion aufgelöst werden:
 +<code cpp>
 +void writeln()
 +{
 +  std::cout << '\n';
 +}
 +
 +template<typename T, typename... Types>
 +void writeln(T t, Types... args)
 +{
 +  std::cout << t;
 +  writeln(args...)
 +}
 +</code>
 +So lässt sich eine Funktion mit variabler Anzahl von Parametern nutzen:
 +<code cpp>
 +  writeln();
 +  writeln("Hallo");
 +  writeln("C++", 17);
 +</code>
 +==== Faltausdrücke ====
 +
 +Ab [[begriffe#C++17]] löst ein [[begriffe#Faltausdruck]] 
 +dies eleganter:
 +<code cpp>
 +template<typename... Types>
 +void writeln(Types... args)
 +{
 +  (std::cout << ... << args) << '\n';
 +}
 +</code>
 +Links-/Rechts-Faltungen können ein- oder zweistellig sein:
 +|        | einstellig | zweistellig | wird aufgelöst als |
 +| Links-Faltung  | ''%%(... op args)%%'' | ''%%(init op ... op args)%%'' | ''(%%%%([init op arg1]) op arg2) op arg3'' |
 +| Rechts-Faltung | ''%%(args op ... )%%'' | ''%%(args op ... op init)%%'' | ''arg1 op (arg2 op (arg3 [op init])%%%%)  '' |
 +
 +==== auto-Parameter ====
 +<code cpp>
 +auto add(auto x, auto y) { return x+y; }
 +</code>
 +ist ab [[begriffe#C++20]] gleichbedeutend mit
 +<code cpp>
 +template <typename X, typename Y>
 +auto add(X x, Y y) { return x+y; }
 +</code>
 +
 +===== Klassenschablonen =====
 +==== Definition ====
 +Klassenentwürfe, die sich nur durch Konstanten oder Datentypen von Attributen,
 +Methodenparametern oder Rückgabewerten unterscheiden, können als Schablonen definiert werden.
 +Typnamen werden in der Schablonenparameterliste 
 +durch
 +[[.:keywords#class]] oder [[.:keywords#typename]]
 +markiert.
 +
 +Syntax:
 +>  ''template <'' Schablonenparameterliste ''>''
 +>  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()  const;
 +private:
 +  T data[size];
 +  int anzahl;
 +};
 +</code>
 +
 +==== Methoden ====
 +Außerhalb der Klassenschablone definierte Methoden werden wie ihre Klasse mit 
 +''template<''Schablonenparameterliste''>'' eingeleitet.
 +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>::is_full() const
 +{
 +  return anzahl==size;
 +}
 +</code>
 +Spezialisierungen erlauben Sonderverhalten für bestimmte konkrete Klassen.
 +
 +<code cpp>
 +template <>
 +int Stack<char, 40>::is_full() const
 +{
 +  if (anzahl != size) return false;
 +  std::cerr << '\a'; 
 +  return true;
 +}
 +</code>
 +==== Konkretisierung ====
 +Klassenschablonen werden durch 
 +[[.:keywords#typedef]]-Anweisungen,  
 +[[.:keywords#using]]-Anweisungen  
 +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''<'' Schablonenargumentliste ''>''
 +<code cpp>
 +// typedef Stack<int, 100> IntegerStack; // C++98
 +using IntegerStack = Stack<int, 100>; 
 +Stack<double, 1000> s;
 +</code>
 +
 +===== Beschränkungen =====
 +Seit [[kennen:begriffe#C++20]] können Schablonen durch [[Concepts]] 
 +eingeschränkt werden.
  
kennen/schablonen.txt · Zuletzt geändert: 2020-07-27 09:56 von 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki