daniela horn institut für neuroinformatik real-time ... · motivation funktionstemplates...
TRANSCRIPT
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Intensivkurs C++ 10. September 2018 | Daniela Horn 1
Intensivkurs C++
Tag 6: Templates
Daniela Horn
Institut für NeuroinformatikReal-time Computer Vision
10. September 2018
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Themen
1 Motivation
2 Funktionstemplates
3 Klassentemplates
4 Klassentemplates mit templatisierten Methoden
5 Spezielles
6 Metaprogrammierung
7 Aufgaben
Intensivkurs C++ 10. September 2018 | Daniela Horn 2
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Gliederung
1 Motivation
2 Funktionstemplates
3 Klassentemplates
4 Klassentemplates mit templatisierten Methoden
5 Spezielles
6 Metaprogrammierung
7 Aufgaben
Intensivkurs C++ 10. September 2018 | Daniela Horn 3
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Motivierendes Beispiel
1 #include <iostream>
2 #include "myNumberClass.h"
34 int main(void)
5 {
6 int i1 = 5, i2 = 7;
7 double d1 = 5.1, d2 = 5.3;
8 MyNumberClass n1("zwei"), n2("drei");
9 const char * c1 = "abc", * c2 = "bbc";
1011 std::cout << "Das Maximum von " << i1 << " und " << i2 << " ist "
12 << getMaxInt(i1, i2) << std::endl;
1314 std::cout << "Das Maximum von " << d1 << " und " << d2 << " ist "
15 << getMaxDouble(d1, d2) << std::endl;
1617 std::cout << "Das Maximum von " << n1 << " und " << n2 << " ist "
18 << getMaxMyNumberClass(n1, n2) << std::endl;
1920 std::cout << "Das Maximum von " << c1 << " und " << c2 << " ist "
21 << getMaxChar(c1, c2) << std::endl;
2223 return 0;
24 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 4
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Motivierendes Beispiel
1 #include <iostream>
2 #include "myNumberClass.h"
34 int main(void)
5 {
6 int i1 = 5, i2 = 7;
7 double d1 = 5.1, d2 = 5.3;
8 MyNumberClass n1("zwei"), n2("drei");
9 const char * c1 = "abc", * c2 = "bbc";
1011 std::cout << "Das Maximum von " << i1 << " und " << i2 << " ist "
12 << getMaxInt(i1, i2) << std::endl;
1314 std::cout << "Das Maximum von " << d1 << " und " << d2 << " ist "
15 << getMaxDouble(d1, d2) << std::endl;
1617 std::cout << "Das Maximum von " << n1 << " und " << n2 << " ist "
18 << getMaxMyNumberClass(n1, n2) << std::endl;
1920 std::cout << "Das Maximum von " << c1 << " und " << c2 << " ist "
21 << getMaxChar(c1, c2) << std::endl;
2223 return 0;
24 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 4
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Motivierendes Beispiel
1 #include <iostream>
2 #include "myNumberClass.h"
34 int main(void)
5 {
6 int i1 = 5, i2 = 7;
7 double d1 = 5.1, d2 = 5.3;
8 MyNumberClass n1("zwei"), n2("drei");
9 const char * c1 = "abc", * c2 = "bbc";
1011 std::cout << "Das Maximum von " << i1 << " und " << i2 << " ist "
12 << getMax(i1, i2) << std::endl;
1314 std::cout << "Das Maximum von " << d1 << " und " << d2 << " ist "
15 << getMax(d1, d2) << std::endl;
1617 std::cout << "Das Maximum von " << n1 << " und " << n2 << " ist "
18 << getMax(n1, n2) << std::endl;
1920 std::cout << "Das Maximum von " << c1 << " und " << c2 << " ist "
21 << getMax(c1, c2) << std::endl;
2223 return 0;
24 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 5
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Motivierendes Beispiel
1 int getMax(int a, int b) //getMaxInt
2 {
3 if ( a > b )
4 return a;
5 else
6 return b;
7 }
89 double getMax(double a, double b) //getMaxDouble
10 {
11 if ( a > b )
12 return a;
13 else
14 return b;
15 }
1617 MyNumberClass & getMax(MyNumberClass & a, MyNumberClass & b) //getMaxMyNumberClass
18 {
19 if ( a > b )
20 return a;
21 else
22 return b;
23 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 6
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Motivierendes Beispiel
1 const char * getMax(const char * a, const char * b) //getMaxChar
2 {
3 int i = 0;
4 while ( a[i] != ’\0’ && b[i] != ’\0’ )
5 {
6 if ( a[i] > b[i] )
7 return a;
8 else if ( b[i] > a[i] )
9 return b;
10 ++i;
11 }
12 if ( a[i] == ’\0’ )
13 return b;
14 else
15 return a;
16 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 7
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Motivierendes Beispiel
1 class IComparable
2 {
3 public:
4 virtual bool operator>(IComparable & rhs) const = 0;
5 };
67 const IComparable & getMax(const IComparable & a, const IComparable & b)
8 {
9 if ( a > b )
10 return a;
11 else
12 return b;
13 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 8
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Motivierendes Beispiel
1 class IComparable
2 {
3 public:
4 virtual bool operator>(IComparable & rhs) const = 0;
5 };
67 const IComparable & getMax(const IComparable & a, const IComparable & b)
8 {
9 if ( a > b )
10 return a;
11 else
12 return b;
13 }
Aber:
Berücksichtigt keine atomaren Datentypen (int, double, char *)
Interface (abstrakte Basisklasse) muss allen Typen bekannt sein
späte Bindung (langsam)
Intensivkurs C++ 10. September 2018 | Daniela Horn 8
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Warum Templates?!
1 template <typename T>
2 const T & getMax(const T & a, const T & b)
3 {
4 if ( a > b )
5 return a;
6 else
7 return b;
8 }
9 //template <ArgList> z.B. template<typename/class T1, typename/class T2, const int N>
10 //Funktionsdefinition/Funktionsdeklaration
Intensivkurs C++ 10. September 2018 | Daniela Horn 9
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Warum Templates?!
1 template <typename T>
2 const T & getMax(const T & a, const T & b)
3 {
4 if ( a > b )
5 return a;
6 else
7 return b;
8 }
9 //template <ArgList> z.B. template<typename/class T1, typename/class T2, const int N>
10 //Funktionsdefinition/Funktionsdeklaration
Keine Codewiederholung
Datentypunabhängige Programmierung
AlgorithmenDatenstrukturen
Keine strenge Klassenhierarchie nötig
Schnell zur Laufzeit
Intensivkurs C++ 10. September 2018 | Daniela Horn 9
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Und char *?!
1 template <>
2 const char * & getMax/*<char*>*/(const char * & a, const char * & b)
3 {
4 int i = 0;
5 while ( a[i] != ’\0’ && b[i] != ’\0’ )
6 {
7 if ( a[i] > b[i] )
8 return a;
9 else if ( b[i] > a[i] )
10 return b;
11 ++i;
12 }
13 if ( a[i] == ’\0’ )
14 return b;
15 else
16 return a;
17 }
18 //template <>
19 //Funktionsdefinition/Funktionsdeklaration
Template-Spezialisierung
Intensivkurs C++ 10. September 2018 | Daniela Horn 10
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Gliederung
1 Motivation
2 Funktionstemplates
3 Klassentemplates
4 Klassentemplates mit templatisierten Methoden
5 Spezielles
6 Metaprogrammierung
7 Aufgaben
Intensivkurs C++ 10. September 2018 | Daniela Horn 11
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Aufruf von Funktionstemplates
1 template <typename T>
2 const T & getMax(const T & a, const T & b)
3 {
4 return a > b ? a : b;
5 }
67 int main()
8 {
9 std::cout << getMax<double>(2.3, 2.4) << std::endl;
1011 std::cout << getMax(2.3, 2.4) << std::endl;
12 std::cout << getMax(2, 3) << std::endl;
1314 std::cout << getMax(2, 3.4) << std::endl;
1516 return 0;
17 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 12
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Aufruf von Funktionstemplates
1 template <typename T>
2 const T & getMax(const T & a, const T & b)
3 {
4 return a > b ? a : b;
5 }
67 int main()
8 {
9 std::cout << getMax<double>(2.3, 2.4) << std::endl;
1011 std::cout << getMax(2.3, 2.4) << std::endl;
12 std::cout << getMax(2, 3) << std::endl;
1314 std::cout << getMax(2, 3.4) << std::endl;
1516 return 0;
17 }
Wenn der Compiler den Typ ableiten kann, braucht man ihn nichthinzuschreiben.
Es wird keine implizite Typkonvertierung durchgeführt, um dieTemplate-Parameter abzuleiten.
Intensivkurs C++ 10. September 2018 | Daniela Horn 12
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Aufruf von Funktionstemplates
1 template <typename T>
2 const T & getMax(const T & a, const T & b)
3 {
4 return a > b ? a : b;
5 }
67 int main()
8 {
9 std::cout << getMax<double>(2.3, 2.4) << std::endl;
1011 std::cout << getMax(2.3, 2.4) << std::endl;
12 std::cout << getMax(2, 3) << std::endl;
1314 std::cout << getMax(2, 3.4) << std::endl;
1516 return 0;
17 }
Wenn der Compiler den Typ ableiten kann, braucht man ihn nichthinzuschreiben.
Es wird keine implizite Typkonvertierung durchgeführt, um dieTemplate-Parameter abzuleiten.
Intensivkurs C++ 10. September 2018 | Daniela Horn 12
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Aufruf von Funktionstemplates
Argumente passend casten
1 cout << getMax(static_cast<double>2, 3.4) << endl;
Typ von T explizit angeben
1 cout << getMax<double>(2, 3.4) << endl;
Intensivkurs C++ 10. September 2018 | Daniela Horn 13
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Aufruf von Funktionstemplates
Argumente passend casten
1 cout << getMax(static_cast<double>2, 3.4) << endl;
Typ von T explizit angeben
1 cout << getMax<double>(2, 3.4) << endl;
Parameter mit voneinander unabhängigen Typen angeben
1 template <typename T1, typename T2>
2 const T1 & getMax(const T1 & a, const T2 & b)
3 {
4 if ( a > b )
5 return a;
6 else
7 return b;
8 }
Was ist hier das Problem?
Intensivkurs C++ 10. September 2018 | Daniela Horn 13
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Aufruf von Funktionstemplates
1 template <typename T1, typename T2>
2 const T1 & getMax(const T1 & a, const T2 & b)
3 {
4 if ( a > b )
5 return a;
6 else
7 return b;
8 }
Probleme:
Rückgabetyp hängt von der Eingabereihenfolge der Argumente ab
führt zu unerwünschtem Verhalten
Bsp.: getMax(66.4, 42) vs. getMax(42, 66.4)
Intensivkurs C++ 10. September 2018 | Daniela Horn 14
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Aufruf von Funktionstemplates
Neuer Templateparameter für Rückgabewert
1 template <typename T1, typename T2, typename TR>
2 const TR & getMax(const T1 & a, const T2 & b)
3 {
4 if ( a > b )
5 return a;
6 else
7 return b;
8 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 15
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Aufruf von Funktionstemplates
Neuer Templateparameter für Rückgabewert
1 template <typename T1, typename T2, typename TR>
2 const TR & getMax(const T1 & a, const T2 & b)
3 {
4 if ( a > b )
5 return a;
6 else
7 return b;
8 }
Probleme?
Intensivkurs C++ 10. September 2018 | Daniela Horn 15
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Aufruf von Funktionstemplates
Rückgabetyp kann nicht automatisch abgeleitet werden
Argumentliste muss explizit angegeben werden
1 getMax<int,double,double>(42,66.6);
Intensivkurs C++ 10. September 2018 | Daniela Horn 16
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Aufruf von Funktionstemplates
Rückgabetyp kann nicht automatisch abgeleitet werden
Argumentliste muss explizit angegeben werden
1 getMax<int,double,double>(42,66.6);
Argumentliste kann verkürzt werden, wenn Reihenfolge derParameterliste geändert wird
1 template <typename TR, typename T1, typename T2>
1 getMax<double>(42,66.6);
Intensivkurs C++ 10. September 2018 | Daniela Horn 16
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Aufruf von Funktionstemplates
Rückgabetyp kann nicht automatisch abgeleitet werden
Argumentliste muss explizit angegeben werden
1 getMax<int,double,double>(42,66.6);
Argumentliste kann verkürzt werden, wenn Reihenfolge derParameterliste geändert wird
1 template <typename TR, typename T1, typename T2>
1 getMax<double>(42,66.6);
Seit C++14 ist automatische Ableitung durch Compiler möglich:
1 template <typename T1, typename T2>
2 auto getMax(const T1 & a, const T2 & b)
3 { ... }
Intensivkurs C++ 10. September 2018 | Daniela Horn 16
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Templates und Compiler
Templates werden in 2 Schritten kompiliert1 Templatecode selbst2 Instanziierter Code
soweit möglich wird in beiden Schritten Code überprüft1 Syntaxfehler1 nicht auf Template-Parametern basierende Eigenschaften,
z. B. unbekannte Funktionsnamen2 Instanzen wie nicht-Template Code
=⇒ Kompilierung dauert länger
=⇒ Probleme mit Linker
Intensivkurs C++ 10. September 2018 | Daniela Horn 17
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Inclusion Model
Szenario:
Funktionstemplate wird in .h deklariert und .cpp definiert. Funktion wird ausanderer .cpp aufgerufen (z. B. in main() ).
Intensivkurs C++ 10. September 2018 | Daniela Horn 18
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Inclusion Model
Szenario:
Funktionstemplate wird in .h deklariert und .cpp definiert. Funktion wird ausanderer .cpp aufgerufen (z. B. in main() ).
Linkerfehler: Definition des Funktionstemplates wurde nichtinstanziiert
Intensivkurs C++ 10. September 2018 | Daniela Horn 18
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Inclusion Model
Szenario:
Funktionstemplate wird in .h deklariert und .cpp definiert. Funktion wird ausanderer .cpp aufgerufen (z. B. in main() ).
Linkerfehler: Definition des Funktionstemplates wurde nichtinstanziiert
Compiler benötigt Informationen zu:
welche Funktion wird instanziiert?mit welchen Templateargumenten soll instanziiert werden?
Informationen werden separat kompiliert
Intensivkurs C++ 10. September 2018 | Daniela Horn 18
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Inclusion Model
Lösung:
Definitionen von Templates kommen zu der Deklaration in dieentsprechende Headerdatei
+ funktioniert- verlängert den Kompiliervorgang
zur Zeit die einfachste und gängigste Herangehensweise
=⇒ Inclusion Model
1 template <typename T> //Deklaration des Templates
2 const T & getMax(const T & a, const T & b)
34 template <typename T> //Definition/Implementierung des Templates
5 const T & getMax(const T & a, const T & b)
6 {
7 if ( a > b )
8 return a;
9 else
10 return b;
11 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 19
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Contra Templates
Template-Verarbeitung ist ein intelligenterer Präprozessor.
(search, copy & replace)
Syntax wird komplexer
Fehler werden undurchsichtiger
Kompilierung dauert länger
Code wird nur bei Instanziierung geprüft (compilerabhängig)
kein »privater« Code
Intensivkurs C++ 10. September 2018 | Daniela Horn 20
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Templates in .cpp-Dateien - eine Ausnahme
1 // Header-File
2 template <typename T>
3 T getMax(T a, T b);
45 // CPP-File
6 template <typename T>
7 T getMax(T a, T b)
8 {
9 return a > b ? a : b;
10 }
1112 template
13 int getMax<int>(int a, int b);
1415 template
16 double getMax<double>(double a, double b);
1718 template
19 char getMax<char>(char a, char b);
Intensivkurs C++ 10. September 2018 | Daniela Horn 21
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Templates in .cpp-Dateien - eine Ausnahme
1 // Header-File
2 template <typename T>
3 T getMax(T a, T b);
45 // CPP-File
6 template <typename T>
7 T getMax(T a, T b)
8 {
9 return a > b ? a : b;
10 }
1112 template
13 int getMax<int>(int a, int b);
1415 template
16 double getMax<double>(double a, double b);
1718 template
19 char getMax<char>(char a, char b);
Explizite Instanziierung der Funktionstemplates
Kompilierbar, aber weniger mögliche Typen sind vorgegeben
Intensivkurs C++ 10. September 2018 | Daniela Horn 21
Partial ordering
1 template <typename T> T getMax(T a, T b) // allgemein
2 // ...
34 template <typename U> U * getMax(U * a, U * b) // spezieller
5 {
6 if ( *a > *b )
7 return a;
8 else
9 return b;
10 }
1112 //template <typename V> const V * getMax(const V * a, const V * b) // noch spezieller
13 //template <typename X> X & getMax(X & a, X & b) // nicht ok
1415 int main()
16 {
17 int a = 3, b = 4;
18 int c = getMax(a, b); // T = int
19 int * d = getMax(&a, &b); // T = int *, U = int ??
20 return 0;
21 }
Partial ordering
1 template <typename T> T getMax(T a, T b) // allgemein
2 // ...
34 template <typename U> U * getMax(U * a, U * b) // spezieller
5 {
6 if ( *a > *b )
7 return a;
8 else
9 return b;
10 }
1112 //template <typename V> const V * getMax(const V * a, const V * b) // noch spezieller
13 //template <typename X> X & getMax(X & a, X & b) // nicht ok
1415 int main()
16 {
17 int a = 3, b = 4;
18 int c = getMax(a, b); // T = int
19 int * d = getMax(&a, &b); // T = int *, U = int ??
20 return 0;
21 }
Der Compiler bindet immer an das spezialisiertesteFunktionstemplate.
Ein Funktionstemplate A ist spezialisierter als ein FunktionstemplateB, wenn jede Argumentliste, die bei A passt, auch bei B passt, abernicht andersherum.
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Mischen von Funktionstemplates und »normalen« Funktionen
1 int getMax(int a, int b)
2 {
3 return a > b ? a : b;
4 }
56 template <typename T>
7 T getMax(T a, T b)
8 {
9 return a > b ? a : b;
10 }
1112 int main()
13 {
14 ... getMax(3, 4);
15 ... getMax(3.0, 4.0);
16 ... getMax(’a’, ’b’);
17 ... getMax<>(3, 4);
18 ... getMax<double>(3, 4);
19 ... getMax(’a’, 4.0);
20 return 0;
21 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 23
Mischen von Funktionstemplates und »normalen« Funktionen
1 int getMax(int a, int b)
2 // ...
34 template <typename T>
5 T getMax(T a, T b)
6 // ...
78 int main()
9 {
10 ... getMax(3, 4);
11 ... getMax(3.0, 4.0);
12 ... getMax(’a’, ’b’);
13 ... getMax<>(3, 4);
14 ... getMax<double>(3, 4);
15 ... getMax(’a’, 4.0);
1617 return 0;
18 }
Mischen von Funktionstemplates und »normalen« Funktionen
1 int getMax(int a, int b)
2 // ...
34 template <typename T>
5 T getMax(T a, T b)
6 // ...
78 int main()
9 {
10 ... getMax(3, 4);
11 ... getMax(3.0, 4.0);
12 ... getMax(’a’, ’b’);
13 ... getMax<>(3, 4);
14 ... getMax<double>(3, 4);
15 ... getMax(’a’, 4.0);
1617 return 0;
18 }
Falls Funktionstemplate vorhanden, fügt der Compiler denKandidatsfunktionen eine Template-Instanz hinzu
Es gilt aber auch: Nicht-Funktionstemplate vor Funktionstemplate!
Overload resolution, implicit conversion sequences
Mischen von Funktionstemplates und »normalen« Funktionen
1 int getMax(int a, int b)
2 // ...
3 template <typename T> T getMax(T a, T b)
4 // ...
56 int main()
7 {
8 ... getMax(3, 4); // Kandidaten: getMax(int, int) und getMax<int>(int, int)
9 ... getMax(3.0, 4.0); // Kandidaten: getMax(int, int) und
10 // getMax<double>(double, double)
11 ... getMax(’a’, ’b’); // Kandidaten: getMax(int, int) und getMax<char>(char,char)
12 ... getMax<>(3, 4); // Kandidaten: getMax<int>(int, int)
13 ... getMax<double>(3,4);// Expliziter Aufruf: getMax<double>(double, double)
14 ... getMax(’a’, 4.0); // Kandidaten: getMax(int, int), Template-Parameter können
15 // nicht abgeleitet werden
16 return 0;
17 }
Falls Funktionstemplate vorhanden, fügt der Compiler denKandidatsfunktionen eine Template-Instanz hinzu
Es gilt aber auch: Nicht-Funktionstemplate vorFunktionstemplate!
Overload resolution, implicit conversion sequences
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Gliederung
1 Motivation
2 Funktionstemplates
3 Klassentemplates
4 Klassentemplates mit templatisierten Methoden
5 Spezielles
6 Metaprogrammierung
7 Aufgaben
Intensivkurs C++ 10. September 2018 | Daniela Horn 26
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates
1 int main()
2 {
3 std::cout << "Bitte geben sie ein paar Zahlen ein (0 zum Beenden): " << std::endl;
4 int cnt = 0;
5 double i[100];
6 do
7 {
8 std::cin >> i[cnt];
9 ++cnt;
10 } while ( i[cnt - 1] != 0);
1112 Stack<double> stack(100);
13 for ( int k = 0; k < cnt; ++k )
14 stack.push(i[k]);
1516 for ( int k = 0; k < cnt; ++k )
17 {
18 std::cout << stack.pop() << std::endl;
19 }
2021 return 0;
22 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 27
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates
1 int main()
2 {
3 std::cout << "Bitte geben sie ein paar Zahlen ein (0 zum Beenden): " << std::endl;
4 int cnt = 0;
5 double i[100];
6 do
7 {
8 std::cin >> i[cnt];
9 ++cnt;
10 } while ( i[cnt - 1] != 0);
1112 Stack<double> stack(100);
13 for ( int k = 0; k < cnt; ++k )
14 stack.push(i[k]);
1516 for ( int k = 0; k < cnt; ++k )
17 {
18 std::cout << stack.pop() << std::endl;
19 }
2021 return 0;
22 }
Container-Klasse Stack<T>
Intensivkurs C++ 10. September 2018 | Daniela Horn 27
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates
1 template <typename T>
2 class Stack
3 {
4 public:
5 Stack<T>(const int size) : m_size(size), m_nextFreeIdx(0)
6 {
7 mp_data = new T[size];
8 }
9 virtual ~Stack<T>() { delete [] mp_data;}
1011 void push(T const newElem)
12 {
13 if ( m_nextFreeIdx == m_size )
14 return;
15 mp_data[m_nextFreeIdx] = newElem;
16 ++m_nextFreeIdx;
17 }
1819 T pop();
2021 private:
22 T* mp_data;
23 const int m_size;
24 int m_nextFreeIdx;
25 };
Intensivkurs C++ 10. September 2018 | Daniela Horn 28
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates
1 template <typename T>
2 class Stack
3 {
4 public:
5 Stack<T>(const int size) : m_size(size), m_nextFreeIdx(0)
6 {
7 mp_data = new T[size];
8 }
9 virtual ~Stack<T>() { delete [] mp_data;}
1011 void push(T const newElem)
12 {
13 if ( m_nextFreeIdx == m_size )
14 return;
15 mp_data[m_nextFreeIdx] = newElem;
16 ++m_nextFreeIdx;
17 }
1819 T pop();
2021 private:
22 T* mp_data;
23 const int m_size;
24 int m_nextFreeIdx;
25 };
Intensivkurs C++ 10. September 2018 | Daniela Horn 28
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates
1 template <typename T>
2 class Stack
3 {
4 public:
56 //...
78 T pop();
910 private:
11 T* mp_data;
12 const int m_size;
13 int m_nextFreeIdx;
14 };
1516 template <typename T>
17 T Stack<T>::pop()
18 {
19 --m_nextFreeIdx;
20 return mp_data[m_nextFreeIdx];
21 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 29
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates
1 template <typename T>
2 class Stack
3 {
4 public:
56 //...
78 T pop();
910 private:
11 T* mp_data;
12 const int m_size;
13 int m_nextFreeIdx;
14 };
1516 template <typename T>
17 T Stack<T>::pop()
18 {
19 --m_nextFreeIdx;
20 return mp_data[m_nextFreeIdx];
21 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 29
Klassentemplates: Syntax
1 template <typename T>
2 class ClassName
3 {
4 // Methodendeklaration / -definition
5 };
67 template <typename U>
8 U ClassName<U>::method(argList)
9 {
10 // Methodendefinition
11 }
Klassentemplates: Syntax
1 template <typename T>
2 class ClassName
3 {
4 // Methodendeklaration / -definition
5 };
67 template <typename U>
8 U ClassName<U>::method(argList)
9 {
10 // Methodendefinition
11 }
Klassentemplates müssen (vorerst) immer mit einemTemplate-Parameter in <> angegeben werden.
Der Klassenname selbst existiert (vorerst) nicht mehr!
Ausnahme(n): Die Template-Klassendefinition und ev. Definition /Deklaration von Konstruktoren / Destruktor (müssen nicht, könnenaber und sollten)
Template-Direktive gilt blockweise. Externe Methodendefinitionenbrauchen eigene Template-Direktive.
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates: Spezialisierung
1 template <>
2 class ClassName<int> // !!!!
3 {
4 // Methodendeklaration / -definition
5 };
67 template <>
8 int ClassName<int>::method(argList)
9 {
10 // Methodendefinition
11 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 31
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates: Spezialisierung
1 template <>
2 class ClassName<int> // !!!!
3 {
4 // Methodendeklaration / -definition
5 };
67 template <>
8 int ClassName<int>::method(argList)
9 {
10 // Methodendefinition
11 }
Syntax wie bei Spezialisierung von Funktionstemplates (beiKlassendefinition auf Klassennamen achten!)
Intensivkurs C++ 10. September 2018 | Daniela Horn 31
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates: Spezialisierung
1 template <typename T, typename U=T>
2 class ClassName
3 {
4 // Methodendeklaration / -definition
5 };
67 //vollständige Spezialisierung von Klassentemplates
8 template <>
9 class ClassName<MyServer, MyClient>
10 {
11 // Methodendeklaration / -definition
12 };
1314 //partielle Spezialisierung von Klassentemplates
15 template <typename U>
16 class ClassName<MyServer, U>
17 {
18 // Methodendeklaration / -definition
19 };
Intensivkurs C++ 10. September 2018 | Daniela Horn 32
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates: Spezialisierung
1 template <typename T, typename U=T>
2 class ClassName
3 {
4 // Methodendeklaration / -definition
5 };
67 //vollständige Spezialisierung von Klassentemplates
8 template <>
9 class ClassName<MyServer, MyClient>
10 {
11 // Methodendeklaration / -definition
12 };
1314 //partielle Spezialisierung von Klassentemplates
15 template <typename U>
16 class ClassName<MyServer, U>
17 {
18 // Methodendeklaration / -definition
19 };
Es gibt KEINE partielle Spezialisierung von Funktionstemplates(auch nicht im neuen Standard)!
Intensivkurs C++ 10. September 2018 | Daniela Horn 32
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates: Default-Parameter
1 template <typename T = int>
2 class ClassName
3 {
4 // Methodendeklaration / -definition
5 };
67 template <typename T = int>
8 T ClassName<T>::method(argList)
9 {
10 // Methodendefinition
11 }
121314 // später
1516 ClassName<> * myClass = new ClassName<>();
Intensivkurs C++ 10. September 2018 | Daniela Horn 33
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates: Default-Parameter
1 template <typename T = int>
2 class ClassName
3 {
4 // Methodendeklaration / -definition
5 };
67 template <typename T = int>
8 T ClassName<T>::method(argList)
9 {
10 // Methodendefinition
11 }
121314 // später
1516 ClassName<> * myClass = new ClassName<>();
Es gibt keine Default-Parameter bei Funktionstemplates
Intensivkurs C++ 10. September 2018 | Daniela Horn 33
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Gliederung
1 Motivation
2 Funktionstemplates
3 Klassentemplates
4 Klassentemplates mit templatisierten Methoden
5 Spezielles
6 Metaprogrammierung
7 Aufgaben
Intensivkurs C++ 10. September 2018 | Daniela Horn 34
Klassentemplates mit Methodentemplates
1 int main(void)
2 {
3 Vector<double, 2> vecD2d_1, vecD2d_2;
4 Vector<int, 2> vecI2d_1, vecI2d_2;
5 Vector<int, 3> vecI3d_1;
67 vecD2d_1.set(0, 1.2); vecD2d_1.set(1, 1.2);
8 vecD2d_2.set(0, 1.2); vecD2d_2.set(1, 3.3);
910 vecI2d_1.set(0, 20); vecI2d_1.set(1, 20);
11 vecI2d_2.set(0, 30); vecI2d_2.set(1, 25);
1213 vecI3d_1.set(0, 2); vecI3d_1.set(1, 2); vecI3d_1.set(2, 2);
1415 vecD2d_1 = vecD2d_2;
16 vecI2d_1 += vecI2d_2;
17 vecD2d_2 += vecI2d_1;
18 vecI2d_2 += vecD2d_1;
1920 Vector<double, 1> vecD1d;
21 Vector<int, 1> vecI1d;
2223 vecD1d.set(4.5);
24 vecI1d.set(12);
2526 vecD1d = 4.6;
27 vecD1d += vecI1d;
2829 return 0;
30 }
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates mit Methodentemplates
1 template <typename T, const int N>
2 class Vector
3 {
4 public:
5 Vector<T, N>& operator=(const Vector<T, N>& other);
67 template <typename T2>
8 Vector<T, N>& operator+=(const Vector<T2, N>& other);
910 void set(const int idx, const T & val);
11 const T & get(const int idx) const { return mp_data[idx]; }
1213 private:
14 T mp_data[N];
15 };
1617 template <typename T, const int N>
18 void Vector<T, N>::set(const int idx, const T & val)
19 {
20 this->mp_data[idx] = val;
21 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 36
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates mit Methodentemplates
1 template <typename T, const int N>
2 class Vector
3 {
4 public:
5 Vector<T, N>& operator=(const Vector<T, N>& other);
67 template <typename T2>
8 Vector<T, N>& operator+=(const Vector<T2, N>& other);
910 void set(const int idx, const T & val);
11 const T & get(const int idx) const { return mp_data[idx]; }
1213 private:
14 T mp_data[N];
15 };
1617 template <typename T, const int N>
18 void Vector<T, N>::set(const int idx, const T & val)
19 {
20 this->mp_data[idx] = val;
21 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 36
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates mit Methodentemplates
1 template <typename T, const int N>
2 Vector<T, N>& Vector<T, N>::operator=(const Vector<T, N>& other)
3 {
4 if ( this == &other )
5 return *this;
6 for ( int i = 0; i < N; ++i )
7 mp_data[i] = other.mp_data[i];
8 return *this;
9 }
1011 template <typename T, const int N>
12 template <typename T2>
13 Vector<T, N>& Vector<T, N>::operator+=(const Vector<T2, N>& other)
14 {
15 for ( int i = 0; i < N; ++i )
16 mp_data[i] += other.get(i);
17 return *this;
18 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 37
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates mit Methodentemplates
1 template <typename T, const int N>
2 Vector<T, N>& Vector<T, N>::operator=(const Vector<T, N>& other)
3 {
4 if ( this == &other )
5 return *this;
6 for ( int i = 0; i < N; ++i )
7 mp_data[i] = other.mp_data[i];
8 return *this;
9 }
1011 template <typename T, const int N>
12 template <typename T2>
13 Vector<T, N>& Vector<T, N>::operator+=(const Vector<T2, N>& other)
14 {
15 for ( int i = 0; i < N; ++i )
16 mp_data[i] += other.get(i);
17 return *this;
18 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 37
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates mit Methodentemplates (Spezialisierung)
1 template <typename T>
2 class Vector<T, 1>
3 {
4 public:
5 Vector<T, 1>& operator=(const Vector<T, 1>& other);
6 Vector<T, 1>& operator=(const T & other);
78 template <typename T2>
9 Vector<T, 1>& operator+=(const Vector<T2, 1>& other);
1011 void set(const T & val);
12 const T & get(void) const { return mp_data; }
1314 private:
15 T mp_data;
16 };
1718 template <typename T>
19 void Vector<T, 1>::set(const T & val)
20 {
21 this->mp_data = val;
22 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 38
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates mit Methodentemplates (Spezialisierung)
1 template <typename T>
2 class Vector<T, 1>
3 {
4 public:
5 Vector<T, 1>& operator=(const Vector<T, 1>& other);
6 Vector<T, 1>& operator=(const T & other);
78 template <typename T2>
9 Vector<T, 1>& operator+=(const Vector<T2, 1>& other);
1011 void set(const T & val);
12 const T & get(void) const { return mp_data; }
1314 private:
15 T mp_data;
16 };
1718 template <typename T>
19 void Vector<T, 1>::set(const T & val)
20 {
21 this->mp_data = val;
22 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 38
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates mit Methodentemplates (Spezialisierung)
1 template <typename T>
2 Vector<T, 1>& Vector<T, 1>::operator=(const Vector<T, 1>& other)
3 {
4 if ( this == &other )
5 return *this;
67 mp_data = other.mp_data;
8 return *this;
9 }
1011 template <typename T>
12 Vector<T, 1>& Vector<T, 1>::operator=(const T & other)
13 {
14 mp_data = other;
15 return *this;
16 }
1718 template <typename T>
19 template <typename T2>
20 Vector<T, 1>& Vector<T, 1>::operator+=(const Vector<T2, 1>& other)
21 {
22 mp_data += other.get();
23 return *this;
24 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 39
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Klassentemplates mit Methodentemplates (Spezialisierung)
1 template <typename T>
2 Vector<T, 1>& Vector<T, 1>::operator=(const Vector<T, 1>& other)
3 {
4 if ( this == &other )
5 return *this;
67 mp_data = other.mp_data;
8 return *this;
9 }
1011 template <typename T>
12 Vector<T, 1>& Vector<T, 1>::operator=(const T & other)
13 {
14 mp_data = other;
15 return *this;
16 }
1718 template <typename T>
19 template <typename T2>
20 Vector<T, 1>& Vector<T, 1>::operator+=(const Vector<T2, 1>& other)
21 {
22 mp_data += other.get();
23 return *this;
24 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 39
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Gliederung
1 Motivation
2 Funktionstemplates
3 Klassentemplates
4 Klassentemplates mit templatisierten Methoden
5 Spezielles
6 Metaprogrammierung
7 Aufgaben
Intensivkurs C++ 10. September 2018 | Daniela Horn 40
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Exkurs: Zugriffskontrolle
public: uneingeschränkter Zugriffprivate: Zugriff nur innerhalb derselben Klasseprotected: Zugriff innerhalb derselben Klasse und in allen vonihr abgeleiteten Klassen
Intensivkurs C++ 10. September 2018 | Daniela Horn 41
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Exkurs: Zugriffskontrolle
public: uneingeschränkter Zugriffprivate: Zugriff nur innerhalb derselben Klasseprotected: Zugriff innerhalb derselben Klasse und in allen vonihr abgeleiteten Klassenfriend: gibt einer bestimmten Funktion oder Klasse Zugriff aufals private oder protected deklarierte member der mitfriend-Deklaration markierten Klasse
1 class MagicNumber
2 {
3 private:
4 int m_magicNumber = 42;
5 friend void printNumber(MagicNumber numberClass);
6 };
78 static void printNumber(MagicNumber numberClass);
9 {
10 cout << numberClass.m_magicNumber << endl;
11 }
Intensivkurs C++ 10. September 2018 | Daniela Horn 41
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Speziell: friend-Deklarationen von Templates
1 template<typename T>
2 class A
3 {...};
45 template<typename T>
6 void f(T a)
7 {...}
89 class B
10 {
11 template<typename T>
12 friend void f(T a);
1314 template<typename T>
15 friend class A;
1617 private:
18 double m_mySecretNumber;
19 };
Syntax erwartungsgemäß (Achtung A nicht A<T>)
Intensivkurs C++ 10. September 2018 | Daniela Horn 42
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Exkurs: typedef
typedef führt einen Namen als Synonym zu einem bereitsbestehenden Typ ein
wird z. B. verwendet, um komplizierte Namen zu kürzen
Codebeispiel:
1 typedef unsigned long UL;
typedef-Deklarationen führen keine neuen Typen ein,sondern dienen lediglich der Textersetzung
es gelten die gleichen Gültigkeitsbereiche, wie etwa beiVariablen
seit C++11 ebenfalls möglich:
1 using UL = unsigned long;
Intensivkurs C++ 10. September 2018 | Daniela Horn 43
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Speziell: typedef-Deklarationen von Klassentemplates
1 template <typename T> class ComplicatedClassNameA {...};
23 template <typename U, typename V> class ComplicatedClassNameB {...};
45 template <typename T> typedef ComplicatedClassNameA<T> A;
6 // compile error
78 template <typename V> typedef ComplicatedClassNameB<double, V> B;
9 // compile error
1011 template <typename T> class A {
12 typedef ComplicatedClassNameA<T> Type;
13 };
1415 template <typename V> class B {
16 typedef ComplicatedClassNameB<double, V> Type;
17 };
1819 // kurz darauf
20 A<int>::Type a;
21 B<float>::Type b;
Intensivkurs C++ 10. September 2018 | Daniela Horn 44
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Speziell: typedef-Deklarationen von Klassentemplates
1 template <typename T> class ComplicatedClassNameA {...};
23 template <typename U, typename V> class ComplicatedClassNameB {...};
45 template <typename T> typedef ComplicatedClassNameA<T> A;
6 // compile error
78 template <typename V> typedef ComplicatedClassNameB<double, V> B;
9 // compile error
1011 template <typename T> class A {
12 typedef ComplicatedClassNameA<T> Type;
13 };
1415 template <typename V> class B {
16 typedef ComplicatedClassNameB<double, V> Type;
17 };
1819 // kurz darauf
20 A<int>::Type a;
21 B<float>::Type b;
typedef kann nicht templatisiert werden
Man muss sich mit einem Trick helfen
Intensivkurs C++ 10. September 2018 | Daniela Horn 44
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Speziell: typedef-Deklarationen von Klassentemplates
1 template <typename T> class ComplicatedClassNameA {...};
23 template <typename T> class A {
4 typedef ComplicatedClassNameA<T> Type;
5 };
67 // ab C++11 auch
8 template <typename T>
9 using A = ComplicatedClassNameA<T>;
1011 // kurz darauf (ab C++03)
12 A<int>::Type a;
1314 // oder aber (ab C++11)
15 A<int> a;
typedef kann nicht templatisiert werden
Man muss sich mit einem Trick helfen
Intensivkurs C++ 10. September 2018 | Daniela Horn 45
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Gliederung
1 Motivation
2 Funktionstemplates
3 Klassentemplates
4 Klassentemplates mit templatisierten Methoden
5 Spezielles
6 Metaprogrammierung
7 Aufgaben
Intensivkurs C++ 10. September 2018 | Daniela Horn 46
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Metaprogrammierung
Erstellung von Programmcode, der anderen Programmcode erzeugt
Häufig (aber nicht ausschließlich) im Zusammenhang mit Templates:Templatemetaprogrammierung
TMP: Code wird zur Übersetzungszeit ausgewertet
=⇒ Verkürzung der Laufzeit
Fehler durch Automatisierung können vermindert werden
Programmiersprache kann durch Programmierer um neueKonstruktionen erweitert werden
Ziel: mehr Funktionalität mit weniger Aufwand
Motivation: Performance und/oder Vereinfachung von Interfaces
Intensivkurs C++ 10. September 2018 | Daniela Horn 47
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Ausblick: Metaprogrammierung
1 template <typename T>
2 class isBool
3 {
4 public:
5 static const bool val = false;
6 };
78 template <>
9 class isBool<bool>
10 {
11 public:
12 static const bool val = true;
13 };
1415 int main()
16 {
17 std::cout << isBool<double>::val << std::endl;
18 std::cout << isBool<bool>::val << std::endl;
19 return 0;
20 }
Spezialisierung von Klassentemplate kann als If-Abfrage (Selektion)verstanden werden
Intensivkurs C++ 10. September 2018 | Daniela Horn 48
Ausblick: Metaprogrammierung
1 template <typename T1, typename T2>
2 class haveSameType
3 {
4 public:
5 static const bool val = false;
6 };
78 template <typename T>
9 class haveSameType<T, T>
10 {
11 public:
12 static const bool val = true;
13 };
1415 template <typename T>
16 void f()
17 {
18 if ( haveSameType<T, double>::val )
19 std::cout << "Bin ein double" << std::endl;
20 else
21 std::cout << "Bin kein double" << std::endl;
22 }
Mit diesem Klassentemplate ist (eine Art) funktionsinterneTemplate-Spezialisierung möglich
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Ausblick: Metaprogrammierung
1 template <const int n>
2 class faculty
3 {
4 public:
5 static const int val = faculty<n - 1>::val * n;
6 };
78 template <>
9 class faculty<1>
10 {
11 public:
12 static const int val = 1;
13 };
1415 int main()
16 {
17 std::cout << "Die Fakultaet von 5 ist " << faculty<5>::val << std::endl;
18 return 0;
19 }
Klassentemplates können als for-Schleife (Rekursion) implementiertwerden
Template-Spezialisierung dient als Abbruchbedingung
Intensivkurs C++ 10. September 2018 | Daniela Horn 50
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Gliederung
1 Motivation
2 Funktionstemplates
3 Klassentemplates
4 Klassentemplates mit templatisierten Methoden
5 Spezielles
6 Metaprogrammierung
7 Aufgaben
Intensivkurs C++ 10. September 2018 | Daniela Horn 51
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Aufgabe 1: Umsortieren (25 Punkte)
Implementieren Sie ein Funktionstemplate, das ein Array eines parametri-sierten Typs und dessen Länge entgegennimmt. Ändern Sie die Reihenfol-ge der Elemente so, dass zuerst das größte Element, dann das kleinste,dann das zweitgrößte, dann das zweitkleinste, usw. angeordnet sind. Vomparametrisierten Typ darf nur vorausgesetzt werden, dass er den Operator< unterstützt und kopiert werden kann. Testen Sie ihre Funktion mit den Ty-pen int, double und einem von Ihnen selbst definierten Typ. EventuelleMembervariablen können Sie public deklarieren und direkt zuweisen.
Hinweis: Um die Ausgabe zu erleichtern, soll die neue Reihenfolge zu-nächst in einem Array zwischengespeichert werden. Stellen Sie sicher, dassalle Elemente aufgenommen werden können.
Intensivkurs C++ 10. September 2018 | Daniela Horn 52
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Aufgabe 2: Binärsuche (25 Punkte)
Implementieren Sie eine Binärsuche als Funktionstemplate.Die Funktion soll
ein aufsteigend sortiertes, konstantes Array einesparametrisierten Typs,
dessen Länge,
und einen Wert des parametrisierten Typs
entgegennehmen. Zurückgegeben wird der Index des Elements im Arrayoder -1, falls er nicht in dem Array enthalten ist. Der parametrisierte Typmuss mindestens die Operatoren < und == unterstützen. Schreiben Sie einkurzes Testprogramm, um Ihren Algorithmus zumindest für die Typen int
und double zu testen.
Intensivkurs C++ 10. September 2018 | Daniela Horn 53
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Aufgabe 3: Online-Statistik (25 Punkte)
Schreiben Sie ein Klassentemplate, das über einen numerischen Typ T pa-rametrisiert wird (die Operationen +, *, /, -, <, == können Sie als gegebenvoraussetzen). Der Klasse werden über wiederholten Aufruf ihrer MethodenextValue Werte vom Typ T übergeben. Die übergebenen Werte sollen
NICHT GESPEICHERT werden. Fügen Sie der Klasse Methoden hinzu, die
... das Maximum und Minimum aller bisher übergebenen Wertezurückgeben
... den Mittelwert aller bisher übergebenen Werte zurückgeben
... die Varianz aller bisher übergebenen Werte zurückgeben
Die Rückgabewerte dieser Methoden sollen den Typ T besitzen. Erkennenund behandeln Sie mögliche Fehler. Testen Sie ihre Klasse mindestens fürdie Typen int und double.
Hinweis: Die Varianz kann anhand eines einzelnen Wertes nur annäherndbestimmt werden. Eine entsprechende Formel finden Sie per Google-Suche.
Intensivkurs C++ 10. September 2018 | Daniela Horn 54
Motivation Funktionstemplates Klassentemplates Klassen-/Methodentemplates Spezielles Metaprogrammierung Aufgaben
Aufgabe 4: Metaprogrammierung (25 Punkte)
Schreiben Sie zwei Varianten einer Meta-FunktionFallendeFaktorielle<const int n, const int k>, welchedie Größe
nk = n · (n−1) · · · · · (n− k +1)
berechnet. Sie können k < n voraussetzen. Verwenden Sie dazu einmal dieMeta-Funktion faculty<const int n> aus der Vorlesung und berech-nen Sie in einer zweiten Variante den Wert nur aus den nötigen Faktoren.
Intensivkurs C++ 10. September 2018 | Daniela Horn 55