Einführung in die Generische Programmierung mit C++

604 views
456 views

Published on

Die Wiederverwendung von algorithmischem Code ist schwierig, und generische Programmierung verspricht eine Lösung. Der Vortrag gibt eine Einführung in die generische Programmierung mit C++ anhand eines einfachen Beispiels, das aber doch seine Tücken hat.
Reuse of algorithmic code is difficult, and generic programming is a potential solution. The talk gives a gentle introduction to generic programming in C++, using a simple example which however has some pitfalls.
Web page with further information: http://www.berti-cmm.de/en/techinfo/generic-programming/

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
604
On SlideShare
0
From Embeds
0
Number of Embeds
49
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Einführung in die Generische Programmierung mit C++

  1. 1. Generische Programmierung 1 / 60Generische ProgrammierungGuntram BertiConsulting mathematische MethodenBonn20. Februar 2013
  2. 2. Motivation: Wiederverwendungalgorithmischen CodesMotivationWiederwendungalgorithmischenCodes: Ein Problem?Das Problem:InhaltTraditionelleAnsaetzeLiftenGenerischeProgrammierungFazitGenerische Programmierung 2 / 60
  3. 3. Wiederwendung algorithmischen Codes: Ein Problem?MotivationWiederwendungalgorithmischenCodes: Ein Problem?Das Problem:InhaltTraditionelleAnsaetzeLiftenGenerischeProgrammierungFazitGenerische Programmierung 3 / 60Klassische Implementierung (eines simplen Algorithmus):double sum(double * v, int n) {double s = 0;for(int i = 0; i < n; ++i)s += v[i];return s;}. . . ist das (wieder)verwendbar?
  4. 4. Wiederwendung algorithmischen Codes: Ein Problem?MotivationWiederwendungalgorithmischenCodes: Ein Problem?Das Problem:InhaltTraditionelleAnsaetzeLiftenGenerischeProgrammierungFazitGenerische Programmierung 3 / 60Klassische Implementierung (eines simplen Algorithmus):double sum(double * v, int n) {double s = 0;for(int i = 0; i < n; ++i)s += v[i];return s;}. . . ist das (wieder)verwendbar?typedef double vec3 [3]; vec3 *v3 = ...;→ sum tut’s nicht f¨ur v3: Falsches Zugriffs-Muster
  5. 5. Wiederwendung algorithmischen Codes: Ein Problem?MotivationWiederwendungalgorithmischenCodes: Ein Problem?Das Problem:InhaltTraditionelleAnsaetzeLiftenGenerischeProgrammierungFazitGenerische Programmierung 3 / 60Klassische Implementierung (eines simplen Algorithmus):double sum(double * v, int n) {double s = 0;for(int i = 0; i < n; ++i)s += v[i];return s;}. . . ist das (wieder)verwendbar?typedef double vec3 [3]; vec3 *v3 = ...;→ sum tut’s nicht f¨ur v3: Falsches Zugriffs-Musterint * vi;→ sum tut’s nicht f¨ur die integers in vi: Falscher Werte-Typ
  6. 6. Das Problem:MotivationWiederwendungalgorithmischenCodes: Ein Problem?Das Problem:InhaltTraditionelleAnsaetzeLiftenGenerischeProgrammierungFazitGenerische Programmierung 4 / 60sum ist (grotesk)¨uberspezifiziert!
  7. 7. InhaltMotivationWiederwendungalgorithmischenCodes: Ein Problem?Das Problem:InhaltTraditionelleAnsaetzeLiftenGenerischeProgrammierungFazitGenerische Programmierung 5 / 60✖ Ein Problem: Wiederverwendung algorithmischen Codes✖ Traditionelle Medizin✖ Der generische Ansatz in der Praxis . . .✖ . . . und in der Theorie✖ Diskussion
  8. 8. Traditionelle Kuren
  9. 9. C-Stil genericsMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 7 / 60void* interfaces & casting
  10. 10. C-Stil genericsMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 7 / 60void* interfaces & castingZ.B. C-Standard-Bibliothek quicksort:void qsort (void *base , size_t n, size_t sz ,int (* less )( const void*,const void *));
  11. 11. C-Stil genericsMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 7 / 60void* interfaces & castingZ.B. C-Standard-Bibliothek quicksort:void qsort (void *base , size_t n, size_t sz ,int (* less )( const void*,const void *));Unser sum w¨urde so aussehen:void sum (void* v, int n, int sz , void* res ,void (* plus )( void*, void*, void *));
  12. 12. C-Stil genericsMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 7 / 60void* interfaces & castingZ.B. C-Standard-Bibliothek quicksort:void qsort (void *base , size_t n, size_t sz ,int (* less )( const void*,const void *));Unser sum w¨urde so aussehen:void sum (void* v, int n, int sz , void* res ,void (* plus )( void*, void*, void *));→ Nicht typ-sicher
  13. 13. C-Stil genericsMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 7 / 60void* interfaces & castingZ.B. C-Standard-Bibliothek quicksort:void qsort (void *base , size_t n, size_t sz ,int (* less )( const void*,const void *));Unser sum w¨urde so aussehen:void sum (void* v, int n, int sz , void* res ,void (* plus )( void*, void*, void *));→ Nicht typ-sicher→ Muss typ-spezifische Infos explizit ¨ubergeben (sz)
  14. 14. C-Stil genericsMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 7 / 60void* interfaces & castingZ.B. C-Standard-Bibliothek quicksort:void qsort (void *base , size_t n, size_t sz ,int (* less )( const void*,const void *));Unser sum w¨urde so aussehen:void sum (void* v, int n, int sz , void* res ,void (* plus )( void*, void*, void *));→ Nicht typ-sicher→ Muss typ-spezifische Infos explizit ¨ubergeben (sz)→ keine M¨oglichkeit von Typ-Spezialisierungen
  15. 15. DS-Standardisierung und Code-ReplizierungMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 8 / 60Implementierung f¨ur feste Anzahl Standard-Datenstrukturen
  16. 16. DS-Standardisierung und Code-ReplizierungMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 8 / 60Implementierung f¨ur feste Anzahl Standard-Datenstrukturenz.B. LAPACK: numerische lineare Algebra,Extra-Implementierungen f¨ur float, double, complex, undverschiedene Matrixtypen: sgetrf(), dgbequ()
  17. 17. DS-Standardisierung und Code-ReplizierungMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 8 / 60Implementierung f¨ur feste Anzahl Standard-Datenstrukturenz.B. LAPACK: numerische lineare Algebra,Extra-Implementierungen f¨ur float, double, complex, undverschiedene Matrixtypen: sgetrf(), dgbequ()Unser Beispiel:double sum_dbl_array (...);int sum_int_array (...);float sum_flt_list (...);...
  18. 18. DS-Standardisierung und Code-ReplizierungMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 8 / 60Implementierung f¨ur feste Anzahl Standard-Datenstrukturenz.B. LAPACK: numerische lineare Algebra,Extra-Implementierungen f¨ur float, double, complex, undverschiedene Matrixtypen: sgetrf(), dgbequ()Unser Beispiel:double sum_dbl_array (...);int sum_int_array (...);float sum_flt_list (...);...→ Duplizierung f¨ur jeden Anwendungsfall
  19. 19. DS-Standardisierung und Code-ReplizierungMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 8 / 60Implementierung f¨ur feste Anzahl Standard-Datenstrukturenz.B. LAPACK: numerische lineare Algebra,Extra-Implementierungen f¨ur float, double, complex, undverschiedene Matrixtypen: sgetrf(), dgbequ()Unser Beispiel:double sum_dbl_array (...);int sum_int_array (...);float sum_flt_list (...);...→ Duplizierung f¨ur jeden Anwendungsfall→ in der Praxis oft inline mit cut & paste
  20. 20. DS-Standardisierung und Code-ReplizierungMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 8 / 60Implementierung f¨ur feste Anzahl Standard-Datenstrukturenz.B. LAPACK: numerische lineare Algebra,Extra-Implementierungen f¨ur float, double, complex, undverschiedene Matrixtypen: sgetrf(), dgbequ()Unser Beispiel:double sum_dbl_array (...);int sum_int_array (...);float sum_flt_list (...);...→ Duplizierung f¨ur jeden Anwendungsfall→ in der Praxis oft inline mit cut & paste→ Wartbarkeit ist ein Albtraum
  21. 21. Wiederverwendung mit MakrosMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 9 / 60#define MAX(a, b) ( (a) <= (b) ? (a) : (b) )
  22. 22. Wiederverwendung mit MakrosMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 9 / 60#define MAX(a, b) ( (a) <= (b) ? (a) : (b) )F¨ur die Summe wird’s schon schwierig:#define SUM(v, n, type) ????
  23. 23. Wiederverwendung mit MakrosMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 9 / 60#define MAX(a, b) ( (a) <= (b) ? (a) : (b) )F¨ur die Summe wird’s schon schwierig:#define SUM(v, n, type) ????Also eher#define DEFINE_SUM (type) type sum_ ## type (type* v, int n) { type res = 0; ... }DEFINE_SUM (float )DEFINE_SUM (double )
  24. 24. Wiederverwendung mit MakrosMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 9 / 60#define MAX(a, b) ( (a) <= (b) ? (a) : (b) )F¨ur die Summe wird’s schon schwierig:#define SUM(v, n, type) ????Also eher#define DEFINE_SUM (type) type sum_ ## type (type* v, int n) { type res = 0; ... }DEFINE_SUM (float )DEFINE_SUM (double )→ Makro-Definition ausserhalb der Sprache
  25. 25. Wiederverwendung mit MakrosMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 9 / 60#define MAX(a, b) ( (a) <= (b) ? (a) : (b) )F¨ur die Summe wird’s schon schwierig:#define SUM(v, n, type) ????Also eher#define DEFINE_SUM (type) type sum_ ## type (type* v, int n) { type res = 0; ... }DEFINE_SUM (float )DEFINE_SUM (double )→ Makro-Definition ausserhalb der Sprache→ keine M¨oglichkeit von Typ-Spezialisierungen
  26. 26. Wiederverwendung mit MakrosMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 9 / 60#define MAX(a, b) ( (a) <= (b) ? (a) : (b) )F¨ur die Summe wird’s schon schwierig:#define SUM(v, n, type) ????Also eher#define DEFINE_SUM (type) type sum_ ## type (type* v, int n) { type res = 0; ... }DEFINE_SUM (float )DEFINE_SUM (double )→ Makro-Definition ausserhalb der Sprache→ keine M¨oglichkeit von Typ-Spezialisierungen→ Explizite Vorab-Instantiierung n¨otig
  27. 27. Kapselung vs. WiederverwendungMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 10 / 60Objektorientierung heisst oft Datenkapselungclass Array {virtual Num sum() = 0;// ...};class DoubleArray : Array {virtual double sum();};class IntArray : Array {virtual int sum();};
  28. 28. Kapselung vs. WiederverwendungMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 10 / 60Objektorientierung heisst oft Datenkapselungclass Array {virtual Num sum() = 0;// ...};class DoubleArray : Array {virtual double sum();};class IntArray : Array {virtual int sum();};→ Neu-Implementierung von sum pro Subklasse
  29. 29. Kapselung vs. WiederverwendungMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 10 / 60Objektorientierung heisst oft Datenkapselungclass Array {virtual Num sum() = 0;// ...};class DoubleArray : Array {virtual double sum();};class IntArray : Array {virtual int sum();};→ Neu-Implementierung von sum pro Subklasse→ ¨ubertriebene Datenkapselung verhindert Wiederverwendung:Algorithmen-Implementierung ist in Klasse vergraben
  30. 30. Kapselung vs. WiederverwendungMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 10 / 60Objektorientierung heisst oft Datenkapselungclass Array {virtual Num sum() = 0;// ...};class DoubleArray : Array {virtual double sum();};class IntArray : Array {virtual int sum();};→ Neu-Implementierung von sum pro Subklasse→ ¨ubertriebene Datenkapselung verhindert Wiederverwendung:Algorithmen-Implementierung ist in Klasse vergraben→ Beispiel: std::string::find xxx()
  31. 31. Objekt-orientierte Versuche: PolymorphieMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 11 / 60class Num { virtual Num& operator+=(Num&) = 0; };
  32. 32. Objekt-orientierte Versuche: PolymorphieMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 11 / 60class Num { virtual Num& operator+=(Num&) = 0; };class Dbl : Num { Num& operator+=(Num&); };class Int : Num { Num& operator+=(Num&); };
  33. 33. Objekt-orientierte Versuche: PolymorphieMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 11 / 60class Num { virtual Num& operator+=(Num&) = 0; };class Dbl : Num { Num& operator+=(Num&); };class Int : Num { Num& operator+=(Num&); };Num* sum(Num** v, int n){Num* s = v[0]->zero ();for(int i=0; i<n; ++i)*s += *v[i];return s;}Dbl* v[8] = { new Dbl(0), ..};Num* s = sum(v, 8) // Error
  34. 34. Objekt-orientierte Versuche: PolymorphieMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 11 / 60class Num { virtual Num& operator+=(Num&) = 0; };class Dbl : Num { Num& operator+=(Num&); };class Int : Num { Num& operator+=(Num&); };Num* sum(Num** v, int n){Num* s = v[0]->zero ();for(int i=0; i<n; ++i)*s += *v[i];return s;}Dbl* v[8] = { new Dbl(0), ..};Num* s = sum(v, 8) // ErrorNum* v[7] = { new Dbl(0), ..};Num* s1 = sum(v, 8); // OK
  35. 35. Objekt-orientierte Versuche: PolymorphieMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 11 / 60class Num { virtual Num& operator+=(Num&) = 0; };class Dbl : Num { Num& operator+=(Num&); };class Int : Num { Num& operator+=(Num&); };Num* sum(Num** v, int n){Num* s = v[0]->zero ();for(int i=0; i<n; ++i)*s += *v[i];return s;}Dbl* v[8] = { new Dbl(0), ..};Num* s = sum(v, 8) // ErrorNum* v[7] = { new Dbl(0), ..};Num* s1 = sum(v, 8); // OKv[9] = new Int (5);Num* s2 = sum(v, 8); // Bumm
  36. 36. Objekt-orientierte Versuche: PolymorphieMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 11 / 60class Num { virtual Num& operator+=(Num&) = 0; };class Dbl : Num { Num& operator+=(Num&); };class Int : Num { Num& operator+=(Num&); };Num* sum(Num** v, int n){Num* s = v[0]->zero ();for(int i=0; i<n; ++i)*s += *v[i];return s;}Dbl* v[8] = { new Dbl(0), ..};Num* s = sum(v, 8) // ErrorNum* v[7] = { new Dbl(0), ..};Num* s1 = sum(v, 8); // OKv[9] = new Int (5);Num* s2 = sum(v, 8); // Bumm
  37. 37. Objekt-orientierte Versuche: PolymorphieMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 11 / 60class Num { virtual Num& operator+=(Num&) = 0; };class Dbl : Num { Num& operator+=(Num&); };class Int : Num { Num& operator+=(Num&); };Num* sum(Num** v, int n){Num* s = v[0]->zero ();for(int i=0; i<n; ++i)*s += *v[i];return s;}Dbl* v[8] = { new Dbl(0), ..};Num* s = sum(v, 8) // ErrorNum* v[7] = { new Dbl(0), ..};Num* s1 = sum(v, 8); // OKv[9] = new Int (5);Num* s2 = sum(v, 8); // Bumm→ Wir verlieren Typsicherheit
  38. 38. Objekt-orientierte Versuche: PolymorphieMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 11 / 60class Num { virtual Num& operator+=(Num&) = 0; };class Dbl : Num { Num& operator+=(Num&); };class Int : Num { Num& operator+=(Num&); };Num* sum(Num** v, int n){Num* s = v[0]->zero ();for(int i=0; i<n; ++i)*s += *v[i];return s;}Dbl* v[8] = { new Dbl(0), ..};Num* s = sum(v, 8) // ErrorNum* v[7] = { new Dbl(0), ..};Num* s1 = sum(v, 8); // OKv[9] = new Int (5);Num* s2 = sum(v, 8); // Bumm→ Wir verlieren Typsicherheit→ Vorgegebene Typ-Hierarchie: Eingebaute Typen haben verloren.
  39. 39. Wiederverwendung ist ein Problem!MotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 12 / 60✖ Wiederverwendung von Algorithmen schwierig, keinebefriedigenden traditionellen Ans¨atze:➔ Implementierungen sind ¨uberspezifiziert➔ Typinformationen fehlen / m¨uhsam zu beschaffen➔ Implementierungen oder Daten sind gekapselt➔ Code wird repliziert
  40. 40. Wiederverwendung ist ein Problem!MotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 12 / 60✖ Wiederverwendung von Algorithmen schwierig, keinebefriedigenden traditionellen Ans¨atze:➔ Implementierungen sind ¨uberspezifiziert➔ Typinformationen fehlen / m¨uhsam zu beschaffen➔ Implementierungen oder Daten sind gekapselt➔ Code wird repliziert✖ sum ist ein ganz einfacher Fall . . .➔ Komplexere Datenstrukturen➔ Komplexere Algorithmen➔ Komplexere Hardware
  41. 41. MotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 13 / 60K¨onnen wir das besser?
  42. 42. Idee der generischen ProgrammierungMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 14 / 60
  43. 43. Idee der generischen ProgrammierungMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 14 / 60Algorithms are as insensitive to changes of data structure aspossible.Alexander Stepanov
  44. 44. Idee der generischen ProgrammierungMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 14 / 60Algorithms are as insensitive to changes of data structure aspossible.Alexander StepanovZiel:Mache Implementierungen so allgemein wie m¨oglich . . .
  45. 45. Idee der generischen ProgrammierungMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 14 / 60Algorithms are as insensitive to changes of data structure aspossible.Alexander StepanovZiel:Mache Implementierungen so allgemein wie m¨oglich . . .aber nicht allgemeiner.
  46. 46. Idee der generischen ProgrammierungMotivationTraditionelleAnsaetzeC-Stil genericsDS-StandardisierungMacrosOOWiederverwendungist ein Problem!generic ideaLiftenGenerischeProgrammierungFazitGenerische Programmierung 14 / 60Algorithms are as insensitive to changes of data structure aspossible.Alexander StepanovZiel:Mache Implementierungen so allgemein wie m¨oglich . . .aber nicht allgemeiner.Enttarne & entferne (k¨unstliche) Einschr¨ankungen . . .¨Ubersetze vielf¨altige Syntax der Daten in einheitliche Sprache. . .
  47. 47. Eine Implementierung “liften”
  48. 48. Was ist liften?MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 16 / 60
  49. 49. Was ist liften?MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 16 / 60Lifting seeks to discover a generic algorithm by answering thefollowing fundamental question: What are the minimalrequirements that my data types need to fulfill for thealgorithm to operate correctly and efficiently?Doug Gregor, generic-programming.org
  50. 50. Was ist liften?MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 16 / 60Lifting seeks to discover a generic algorithm by answering thefollowing fundamental question: What are the minimalrequirements that my data types need to fulfill for thealgorithm to operate correctly and efficiently?Doug Gregor, generic-programming.orgMost developers are not cut out to create these genericcomponents, but most can use them. The process for creatingthem is a non-process. You fiddle, you scratch your head, [. . . ]you rip your code up over and over (and over and over).Marshall Cline, The C++ FAQ
  51. 51. Wie man eine Implementierung generisch machtMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 17 / 60Die (impliziten) Annahmen von sum:double sum(double *v, int n) {double s = 0.0;for(int i = 0; i < n; ++i) {s += v[i];}return s;}✖ Typ ist double✖ Daten stehen in array✖ (ohne L¨ucken)
  52. 52. Wie man eine Implementierung generisch machtMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 17 / 60Die (impliziten) Annahmen von sum:double sum(double *v, int n) {double s = 0.0;for(int i = 0; i < n; ++i) {s += v[i];}return s;}✖ Typ ist double✖ Daten stehen in array✖ (ohne L¨ucken)
  53. 53. Wie man eine Implementierung generisch machtMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 17 / 60Die (impliziten) Annahmen von sum:double sum(double *v, int n) {double s = 0.0;for(int i = 0; i < n; ++i) {s += v[i];}return s;}✖ Typ ist double✖ Daten stehen in array✖ (ohne L¨ucken)
  54. 54. Wie man eine Implementierung generisch machtMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 17 / 60Die (impliziten) Annahmen von sum:double sum(double *v, int n) {double s = 0.0;for(int i = 0; i < n; ++i) {s += v[i];}return s;}✖ Typ ist double✖ Daten stehen in array✖ (ohne L¨ucken)
  55. 55. Wie man eine Implementierung generisch machtMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 17 / 60Die (impliziten) Annahmen von sum:double sum(double *v, int n) {double s = 0.0;for(int i = 0; i < n; ++i) {s += v[i];}return s;}✖ Typ ist double✖ Daten stehen in array✖ (ohne L¨ucken)
  56. 56. Generische Summe: Weg mit doubleMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 18 / 60Weg mit der Typ-ist-double Einschr¨ankung:double sum(double* v, int n) {double s = 0.0;for(int i = 0; i < n; ++i) {s = s + v[i];}return s;}
  57. 57. Generische Summe: Weg mit doubleMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 18 / 60Weg mit der Typ-ist-double Einschr¨ankung:double sum(double* v, int n) {double s = 0.0;for(int i = 0; i < n; ++i) {s = s + v[i];}return s;}Das war einfach. Vielleicht zu einfach . . . ?
  58. 58. Generische Summe: Weg mit doubleMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 18 / 60Weg mit der Typ-ist-double Einschr¨ankung:template<class T>T sum(T* v, int n) {T s = 0;for(int i = 0; i < n; ++i) {s = s + v[i];}return s;}Das war einfach. Vielleicht zu einfach . . . ?
  59. 59. Generische Summe: Weg mit arrays ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 19 / 60Weg mit der Array-Einschr¨ankung . . .template <class T>T sum(T* v, int n) {T s = 0;for(int i = 0; i < n; ++i) {s = s + v[i];}return s;}
  60. 60. Generische Summe: Weg mit arrays ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 19 / 60Weg mit der Array-Einschr¨ankung . . .template <class T>T sum(T* v, int n) {T s = 0;for(int i = 0; i < n; ++i) {s = s + v[i];}return s;}
  61. 61. Generische Summe: Weg mit arrays ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 19 / 60Weg mit der Array-Einschr¨ankung . . .template <class T>T sum(T* v, int n) {T s = 0;for(int i = 0; i < n; ++i) {s = s + *v;++v;}return s;}
  62. 62. Generische Summe: Weg mit arrays ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 19 / 60Weg mit der Array-Einschr¨ankung . . .template <class T>T sum(T* v, int n) {T s = 0;for(int i = 0; i < n; ++i) {s = s + *v;++v;}return s;}
  63. 63. Generische Summe: Weg mit arrays ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 19 / 60Weg mit der Array-Einschr¨ankung . . .template <class T>T sum(T* v, T* end) { // end == v + nT s = 0;while(v != end) {s = s + *v;++v;}return s;}
  64. 64. Generische Summe: Weg mit arrays ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 20 / 60Weg mit der array-Einschr¨ankung . . .template <class T>T sum(T* v, T* end) {T s = 0;while (v != end) {s = s + *v;++v;}return s;}Was muss das Argument v k¨onnen?
  65. 65. Generische Summe: Weg mit arrays ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 20 / 60Weg mit der array-Einschr¨ankung . . .template <class T>T sum(T* v, T* end) {T s = 0;while (v != end) {s = s + *v;++v;}return s;}Was muss das Argument v k¨onnen?✖ Vergleich, v != end
  66. 66. Generische Summe: Weg mit arrays ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 20 / 60Weg mit der array-Einschr¨ankung . . .template <class T>T sum(T* v, T* end) {T s = 0;while (v != end) {s = s + *v;++v;}return s;}Was muss das Argument v k¨onnen?✖ Vergleich, v != end✖ Dereferenz, *v (nur lesend)
  67. 67. Generische Summe: Weg mit arrays ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 20 / 60Weg mit der array-Einschr¨ankung . . .template <class T>T sum(T* v, T* end) {T s = 0;while (v != end) {s = s + *v;++v;}return s;}Was muss das Argument v k¨onnen?✖ Vergleich, v != end✖ Dereferenz, *v (nur lesend)✖ Inkrement, ++v (Pr¨afix-Variante)
  68. 68. Generische Summe: Weg mit arrays ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 20 / 60Weg mit der array-Einschr¨ankung . . .template <class T>T sum(T* v, T* end) {T s = 0;while (v != end) {s = s + *v;++v;}return s;}Was muss das Argument v k¨onnen?✖ Vergleich, v != end✖ Dereferenz, *v (nur lesend)✖ Inkrement, ++v (Pr¨afix-Variante)
  69. 69. Concept: IteratorMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 21 / 60Neue Abstraktion: Iterator (verallgemeinert Array-Zeiger)
  70. 70. Concept: IteratorMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 21 / 60Neue Abstraktion: Iterator (verallgemeinert Array-Zeiger)concept Iterator { // kein C++Iterator & operator ++();value_type operator *();};bool operator !=( Iterator const &, Iterator const &);
  71. 71. Concept: IteratorMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 21 / 60Neue Abstraktion: Iterator (verallgemeinert Array-Zeiger)concept Iterator { // kein C++Iterator & operator ++();value_type operator *();};bool operator !=( Iterator const &, Iterator const &);Sehr geringe Anforderungen, kann breit unterst¨utzt werden!
  72. 72. Concept: IteratorMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 21 / 60Neue Abstraktion: Iterator (verallgemeinert Array-Zeiger)concept Iterator { // kein C++Iterator & operator ++();value_type operator *();};bool operator !=( Iterator const &, Iterator const &);Sehr geringe Anforderungen, kann breit unterst¨utzt werden!F¨ur Erbsenz¨ahler:operator* wird nur 1x an jeder Position aufgerufen (single pass)
  73. 73. Iteratoren: BeispielMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 22 / 60Beispiel: Einfach verkettete Liste
  74. 74. Iteratoren: BeispielMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 22 / 60Beispiel: Einfach verkettete Listestruct List { // rudimentaerint data;List* next; // == 0 am Listen -Ende};
  75. 75. Iteratoren: BeispielMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 22 / 60Beispiel: Einfach verkettete Listestruct List { // rudimentaerint data;List* next; // == 0 am Listen -Ende};struct ListIt { // implementiert Iterator -ConceptList* curr;int operator*() const { return curr ->data; }ListIt & operator++() {curr = curr ->next; return *this; }};
  76. 76. Iteratoren: BeispielMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 22 / 60Beispiel: Einfach verkettete Listestruct List { // rudimentaerint data;List* next; // == 0 am Listen -Ende};struct ListIt { // implementiert Iterator -ConceptList* curr;int operator*() const { return curr ->data; }ListIt & operator++() {curr = curr ->next; return *this; }};inline bool operator!=( ListIt const & a, ListIt const & b){ return a.curr != b.curr; }
  77. 77. Iteratoren: BeispielMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 22 / 60Beispiel: Einfach verkettete Listestruct List { // rudimentaerint data;List* next; // == 0 am Listen -Ende};struct ListIt { // implementiert Iterator -ConceptList* curr;int operator*() const { return curr ->data; }ListIt & operator++() {curr = curr ->next; return *this; }};inline bool operator!=( ListIt const & a, ListIt const & b){ return a.curr != b.curr; }ListIt erlaubt nur Lese-Zugriffe
  78. 78. Generische Summe: Weg mit arrays ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 23 / 60Weg mit der Array-Einschr¨ankung . . .template <class T >T sum(T* v, T* end) {T s = 0;while (v != end) {s += *v;v++;}return s;}
  79. 79. Generische Summe: Weg mit arrays ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 23 / 60Weg mit der Array-Einschr¨ankung . . .template <class Iter>??? sum(Iter v, Iter end) {??? s = 0;while (v != end) {s += *v;v++;}return s;}
  80. 80. Generische Summe: Weg mit arrays ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 23 / 60Weg mit der Array-Einschr¨ankung . . .template <class Iter>??? sum(Iter v, Iter end) {??? s = 0;while (v != end) {s += *v;v++;}return s;}Leider gibt es ein kleines Problem . . .
  81. 81. Den Werte-Typ zur¨uck bekommen: Variante 1MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 24 / 60Versuch 1: Extra Parameter
  82. 82. Den Werte-Typ zur¨uck bekommen: Variante 1MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 24 / 60Versuch 1: Extra Parametertemplate <class Iter ,class T>Tsum(Iter v, Iter end , T init) {T s = init;while (v != end) {s = s + *v;v++;}return s;}
  83. 83. Den Werte-Typ zur¨uck bekommen: Variante 1MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 24 / 60Versuch 1: Extra Parametertemplate <class Iter ,class T>Tsum(Iter v, Iter end , T init) {T s = init;while (v != end) {s = s + *v;v++;}return s;}+ Volle Kontrolle ¨uber Werte-Typ und Init-Wert
  84. 84. Den Werte-Typ zur¨uck bekommen: Variante 1MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 24 / 60Versuch 1: Extra Parametertemplate <class Iter ,class T>Tsum(Iter v, Iter end , T init) {T s = init;while (v != end) {s = s + *v;v++;}return s;}+ Volle Kontrolle ¨uber Werte-Typ und Init-Wert− zwingender Zusatz-Parameter
  85. 85. Den Werte-Typ zur¨uck bekommen: Variante 1MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 24 / 60Versuch 1: Extra Parametertemplate <class Iter ,class T>Tsum(Iter v, Iter end , T init) {T s = init;while (v != end) {s = s + *v;v++;}return s;}+ Volle Kontrolle ¨uber Werte-Typ und Init-Wert− zwingender Zusatz-Parameter− Typ T im Ruf-Kontext bekannt?? (generisch!)
  86. 86. Den Werte-Typ zur¨uckbekommen: Variante 2MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 25 / 60Versuch 2: T als typedef aus dem Iterator
  87. 87. Den Werte-Typ zur¨uckbekommen: Variante 2MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 25 / 60Versuch 2: T als typedef aus dem Iteratorclass ListIt { typedef int value_type ; ... };
  88. 88. Den Werte-Typ zur¨uckbekommen: Variante 2MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 25 / 60Versuch 2: T als typedef aus dem Iteratorclass ListIt { typedef int value_type ; ... };template <class Iter >typename Iter::value typesum(Iter v, Iter end) {typename Iter::value type s = 0;while (v != end) {s = s + *v;v++;}return s;}
  89. 89. Den Werte-Typ zur¨uckbekommen: Variante 2MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 25 / 60Versuch 2: T als typedef aus dem Iteratorclass ListIt { typedef int value_type ; ... };template <class Iter >typename Iter::value typesum(Iter v, Iter end) {typename Iter::value type s = 0;while (v != end) {s = s + *v;v++;}return s;}− Muss bestehende Klassen ¨andern
  90. 90. Den Werte-Typ zur¨uckbekommen: Variante 2MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 25 / 60Versuch 2: T als typedef aus dem Iteratorclass ListIt { typedef int value_type ; ... };template <class Iter >typename Iter::value typesum(Iter v, Iter end) {typename Iter::value type s = 0;while (v != end) {s = s + *v;v++;}return s;}− Muss bestehende Klassen ¨andern− Funktioniert nicht f¨ur Iter = T*
  91. 91. Den Werte-Typ zur¨uckbekommen: Variante 2MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 25 / 60Versuch 2: T als typedef aus dem Iteratorclass ListIt { typedef int value_type ; ... };template <class Iter >typename Iter::value typesum(Iter v, Iter end) {typename Iter::value type s = 0;while (v != end) {s = s + *v;v++;}return s;}− Muss bestehende Klassen ¨andern− Funktioniert nicht f¨ur Iter = T*Brauche nicht-intrusive Abbildung Iter → value type
  92. 92. Den Werte-Typ zur¨uckbekommen: Variante 3MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 26 / 60Versuch 3: Abbildung value : IteratorTyp → WerteTyp
  93. 93. Den Werte-Typ zur¨uckbekommen: Variante 3MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 26 / 60Versuch 3: Abbildung value : IteratorTyp → WerteTypAllgemeiner Fall: I → I::value type
  94. 94. Den Werte-Typ zur¨uckbekommen: Variante 3MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 26 / 60Versuch 3: Abbildung value : IteratorTyp → WerteTypAllgemeiner Fall: I → I::value typetemplate <class I> struct value{ typedef typename I:: value_type value_type ; };
  95. 95. Den Werte-Typ zur¨uckbekommen: Variante 3MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 26 / 60Versuch 3: Abbildung value : IteratorTyp → WerteTypAllgemeiner Fall: I → I::value typetemplate <class I> struct value{ typedef typename I:: value_type value_type ; };F¨ur Zeiger: T* → T
  96. 96. Den Werte-Typ zur¨uckbekommen: Variante 3MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 26 / 60Versuch 3: Abbildung value : IteratorTyp → WerteTypAllgemeiner Fall: I → I::value typetemplate <class I> struct value{ typedef typename I:: value_type value_type ; };F¨ur Zeiger: T* → Ttemplate <class T> struct value <T*> {typedef T type ;};
  97. 97. Den Werte-Typ zur¨uckbekommen: Variante 3MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 26 / 60Versuch 3: Abbildung value : IteratorTyp → WerteTypAllgemeiner Fall: I → I::value typetemplate <class I> struct value{ typedef typename I:: value_type value_type ; };F¨ur Zeiger: T* → Ttemplate <class T> struct value <T*> {typedef T type ;};Unser Iterator: ListIt → int
  98. 98. Den Werte-Typ zur¨uckbekommen: Variante 3MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 26 / 60Versuch 3: Abbildung value : IteratorTyp → WerteTypAllgemeiner Fall: I → I::value typetemplate <class I> struct value{ typedef typename I:: value_type value_type ; };F¨ur Zeiger: T* → Ttemplate <class T> struct value <T*> {typedef T type ;};Unser Iterator: ListIt → inttemplate <> struct value <ListIt > {typedef int type ;};
  99. 99. Den Werte-Typ zur¨uckbekommen: Variante 3MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 26 / 60Versuch 3: Abbildung value : IteratorTyp → WerteTypAllgemeiner Fall: I → I::value typetemplate <class I> struct value{ typedef typename I:: value_type value_type ; };F¨ur Zeiger: T* → Ttemplate <class T> struct value <T*> {typedef T type ;};Unser Iterator: ListIt → inttemplate <> struct value <ListIt > {typedef int type ;};In C++11 ist das etwas einfacher:
  100. 100. Den Werte-Typ zur¨uckbekommen: Variante 3MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 26 / 60Versuch 3: Abbildung value : IteratorTyp → WerteTypAllgemeiner Fall: I → I::value typetemplate <class I> struct value{ typedef typename I:: value_type value_type ; };F¨ur Zeiger: T* → Ttemplate <class T> struct value <T*> {typedef T type ;};Unser Iterator: ListIt → inttemplate <> struct value <ListIt > {typedef int type ;};In C++11 ist das etwas einfacher:template <class I> struct value // C++11{ typedef decltype (I(). operator *()) type; }(Die Bed. dass I einen Default-Konstruktor hat, kann man loswerden. Einen Ref-Qualifier muss man ggf.beseitigen.)
  101. 101. Den Wertetyp zur¨uckbekommenMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 27 / 60Versuch 3: Typ-Abbildung im Einsatz
  102. 102. Den Wertetyp zur¨uckbekommenMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 27 / 60Versuch 3: Typ-Abbildung im Einsatztemplate <class Iter >typename value<Iter>::typesum(Iter v, Iter end) {typename value<Iter>::type s = 0;while (v != end) {s = s + *v;v++;}return s;}
  103. 103. Den Wertetyp zur¨uckbekommenMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 27 / 60Versuch 3: Typ-Abbildung im Einsatztemplate <class Iter >typename value<Iter>::typesum(Iter v, Iter end) {typename value<Iter>::type s = 0;while (v != end) {s = s + *v;v++;}return s;}(In der Standard-Library liefert iterator traits dieFunktionalit¨at von value).
  104. 104. Auf zum Summieren ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 28 / 60vector <int > v(10, 42);assert (sum(v.begin (), v.end ()) == 420);
  105. 105. Auf zum Summieren ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 28 / 60vector <int > v(10, 42);assert (sum(v.begin (), v.end ()) == 420);List L; // ... fill L ...// Annahme List :: begin (), end () implementiertint sl = sum(L.begin (), L.end ());
  106. 106. Auf zum Summieren ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 28 / 60vector <int > v(10, 42);assert (sum(v.begin (), v.end ()) == 420);List L; // ... fill L ...// Annahme List :: begin (), end () implementiertint sl = sum(L.begin (), L.end ());cout << "type numbers :n"double s = sum(istream_iterator <double >( cin),istream_iterator <double >());cout << "sum of numbers : " << s << endl;
  107. 107. Auf zum Summieren ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 28 / 60vector <int > v(10, 42);assert (sum(v.begin (), v.end ()) == 420);List L; // ... fill L ...// Annahme List :: begin (), end () implementiertint sl = sum(L.begin (), L.end ());cout << "type numbers :n"double s = sum(istream_iterator <double >( cin),istream_iterator <double >());cout << "sum of numbers : " << s << endl;vector <string > words ; // fill words ...string all = sum(words .begin (), words .end ()); // UpsWas passiert?
  108. 108. Richtiges neutrales Element?MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 29 / 60template <class Iter >typename value <Iter >:: typesum(Iter v, Iter end) {typename value <Iter >:: type s = 0;while (v != end) {s = s + *v;v++;}return s;}
  109. 109. Richtiges neutrales Element?MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 29 / 60template <class Iter >typename value <Iter >:: typesum(Iter v, Iter end) {typename value <Iter >:: type s = 0;while (v != end) {s = s + *v;v++;}return s;}Der richtige Anfangswert f¨ur strings ist der leere string.
  110. 110. Richtiges neutrales Element?MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 29 / 60template <class Iter >typename value <Iter >:: typesum(Iter v, Iter end) {typename value <Iter >:: type s = 0;while (v != end) {s = s + *v;v++;}return s;}Der richtige Anfangswert f¨ur strings ist der leere string.Brauche neutrales Element zu (T, +)
  111. 111. Das richtige neutrale Element findenMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 30 / 60Wieder gibt es mehrere M¨oglichkeiten:
  112. 112. Das richtige neutrale Element findenMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 30 / 60Wieder gibt es mehrere M¨oglichkeiten:1. Einfach das erste Element des Inputs nehmen
  113. 113. Das richtige neutrale Element findenMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 30 / 60Wieder gibt es mehrere M¨oglichkeiten:1. Einfach das erste Element des Inputs nehmen2. zus¨atzliches init-Argument
  114. 114. Das richtige neutrale Element findenMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 30 / 60Wieder gibt es mehrere M¨oglichkeiten:1. Einfach das erste Element des Inputs nehmen2. zus¨atzliches init-Argument3. Typ-Abbildung analog zu value
  115. 115. Variante 1: Initialisierung mit erstem ElementMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 31 / 60template <class Iter >typename value <Iter >:: typesum(Iter v, Iter end) {typename value <Iter >:: type s = *v; ++v;while (v != end) {s = s + *v;v++;}return s;}
  116. 116. Variante 1: Initialisierung mit erstem ElementMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 31 / 60template <class Iter >typename value <Iter >:: typesum(Iter v, Iter end) {assert(v != end);typename value <Iter >:: type s = *v; ++v;while (v != end) {s = s + *v;v++;}return s;}Nachteil: Kann keine leeren Sequenzen verarbeiten.
  117. 117. Variante 2: Neutrales Element explizit ¨ubergebenMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 32 / 60template <class Iter ,class T>Tsum(Iter v, Iter end , T init) {T s = init;while (v != end) {s = s + *v;v++;}return s;}
  118. 118. Variante 2: Neutrales Element explizit ¨ubergebenMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 32 / 60template <class Iter ,class T>Tsum(Iter v, Iter end , T init) {T s = init;while (v != end) {s = s + *v;v++;}return s;}+ Volle Kontrolle ¨uber Werte-Typ und Init-Wert
  119. 119. Neutrales Element explizit ¨ubergeben: BeispieleMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 33 / 60vector <string > w; // ... fuelle w ...string text = sum(w.begin (), w.end(), string ());
  120. 120. Neutrales Element explizit ¨ubergeben: BeispieleMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 33 / 60vector <string > w; // ... fuelle w ...string text = sum(w.begin (), w.end(), string ());float a[] = {0.5, 1.0, 1.5 };float s = sum(a, a+3, 0); // hmm ...
  121. 121. Neutrales Element explizit ¨ubergeben: BeispieleMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 33 / 60vector <string > w; // ... fuelle w ...string text = sum(w.begin (), w.end(), string ());float a[] = {0.5, 1.0, 1.5 };float s = sum(a, a+3, 0); // hmm ...Die init-Variante ist hochgef¨ahrlich!
  122. 122. Neutrales Element explizit ¨ubergeben: BeispieleMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 33 / 60vector <string > w; // ... fuelle w ...string text = sum(w.begin (), w.end(), string ());float a[] = {0.5, 1.0, 1.5 };float s = sum(a, a+3, 0); // hmm ...Die init-Variante ist hochgef¨ahrlich!vector <unsigned char > w = wuerfel_werfen (N);
  123. 123. Neutrales Element explizit ¨ubergeben: BeispieleMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 33 / 60vector <string > w; // ... fuelle w ...string text = sum(w.begin (), w.end(), string ());float a[] = {0.5, 1.0, 1.5 };float s = sum(a, a+3, 0); // hmm ...Die init-Variante ist hochgef¨ahrlich!vector <unsigned char > w = wuerfel_werfen (N);unsigned s1 = sum(w.begin (),w.end ()); // ohne init
  124. 124. Neutrales Element explizit ¨ubergeben: BeispieleMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 33 / 60vector <string > w; // ... fuelle w ...string text = sum(w.begin (), w.end(), string ());float a[] = {0.5, 1.0, 1.5 };float s = sum(a, a+3, 0); // hmm ...Die init-Variante ist hochgef¨ahrlich!vector <unsigned char > w = wuerfel_werfen (N);unsigned s1 = sum(w.begin (),w.end ()); // ohne initunsigned s2 = sum(w.begin (),w.end () ,0); // mit init
  125. 125. Neutrales Element explizit ¨ubergeben: BeispieleMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 33 / 60vector <string > w; // ... fuelle w ...string text = sum(w.begin (), w.end(), string ());float a[] = {0.5, 1.0, 1.5 };float s = sum(a, a+3, 0); // hmm ...Die init-Variante ist hochgef¨ahrlich!vector <unsigned char > w = wuerfel_werfen (N);unsigned s1 = sum(w.begin (),w.end ()); // ohne initunsigned s2 = sum(w.begin (),w.end () ,0); // mit init... hat aber auch ihr Gutes!
  126. 126. Variante 3: Neutrales Element mit TypemapMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 34 / 60neutral elem sum: ValueType → neutrales Element
  127. 127. Variante 3: Neutrales Element mit TypemapMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 34 / 60neutral elem sum: ValueType → neutrales Elementtemplate <class T> struct neutral_elem_sum{ static T value () { return T(0);} };
  128. 128. Variante 3: Neutrales Element mit TypemapMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 34 / 60neutral elem sum: ValueType → neutrales Elementtemplate <class T> struct neutral_elem_sum{ static T value () { return T(0);} };template <> struct neutral_elem_sum <std :: string >{ static std :: string value (){ return std :: string (); } };
  129. 129. Variante 3: Neutrales Element mit TypemapMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 34 / 60neutral elem sum: ValueType → neutrales Elementtemplate <class T> struct neutral_elem_sum{ static T value () { return T(0);} };template <> struct neutral_elem_sum <std :: string >{ static std :: string value (){ return std :: string (); } };template <> struct neutral_elem_sum <vec3 >{ static vec3 zero () { return vec3 (0 ,0 ,0);} };
  130. 130. Variante 3: Neutrales Element mit TypemapMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 34 / 60neutral elem sum: ValueType → neutrales Elementtemplate <class T> struct neutral_elem_sum{ static T value () { return T(0);} };template <> struct neutral_elem_sum <std :: string >{ static std :: string value (){ return std :: string (); } };template <> struct neutral_elem_sum <vec3 >{ static vec3 zero () { return vec3 (0 ,0 ,0);} };template <class T> struct neutral_elem_sum <matrix <T> >{ static matrix <T> zero (){ return matrix <T>(n=???, m=??? ,0); } };
  131. 131. Das richtige neutrale Element finden: FazitMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 35 / 60Welcher Ansatz ist jetzt am besten?Pro Coninit mehr Kontrolle Bricht Interfaceinit nicht immer bekanntAllgemeiner Gef¨ahrlich1. Element OK alle Typen Bed.: Seq. = ∅Type-Map OK alle Seq. Bed.: Typ hat neutrales E.
  132. 132. Das richtige neutrale Element finden: FazitMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 35 / 60Welcher Ansatz ist jetzt am besten?Pro Coninit mehr Kontrolle Bricht Interfaceinit nicht immer bekanntAllgemeiner Gef¨ahrlich1. Element OK alle Typen Bed.: Seq. = ∅Type-Map OK alle Seq. Bed.: Typ hat neutrales E.✖ init Variante: allgemeine Basis-Version
  133. 133. Das richtige neutrale Element finden: FazitMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 35 / 60Welcher Ansatz ist jetzt am besten?Pro Coninit mehr Kontrolle Bricht Interfaceinit nicht immer bekanntAllgemeiner Gef¨ahrlich1. Element OK alle Typen Bed.: Seq. = ∅Type-Map OK alle Seq. Bed.: Typ hat neutrales E.✖ init Variante: allgemeine Basis-Version✖ Type-Map Variante als Convenience
  134. 134. Das richtige neutrale Element finden: FazitMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 35 / 60Welcher Ansatz ist jetzt am besten?Pro Coninit mehr Kontrolle Bricht Interfaceinit nicht immer bekanntAllgemeiner Gef¨ahrlich1. Element OK alle Typen Bed.: Seq. = ∅Type-Map OK alle Seq. Bed.: Typ hat neutrales E.✖ init Variante: allgemeine Basis-Version✖ Type-Map Variante als Convenience✖ 1. Element Variante bei Typ ohne neutrales Element
  135. 135. Ist die Summe jetzt generisch genug?MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 36 / 60
  136. 136. Ist die Summe jetzt generisch genug?MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 36 / 60struct employee {double salary ;int id;};vector <employee > staff ;// double salaries = sum(staff .begin (), staff .end ());
  137. 137. Ist die Summe jetzt generisch genug?MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 36 / 60struct employee {double salary ;int id;};vector <employee > staff ;// double salaries = sum(staff .begin (), staff .end ());vector <string > words = { "Das", "ist", "ein", "Satz "};string text = sum(words .begin (), words .end ());// " DasisteinSatz "
  138. 138. Ist die Summe jetzt generisch genug?MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 36 / 60struct employee {double salary ;int id;};vector <employee > staff ;// double salaries = sum(staff .begin (), staff .end ());vector <string > words = { "Das", "ist", "ein", "Satz "};string text = sum(words .begin (), words .end ());// " DasisteinSatz "double max_salary = ??
  139. 139. Ist die Summe jetzt generisch genug?MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 36 / 60struct employee {double salary ;int id;};vector <employee > staff ;// double salaries = sum(staff .begin (), staff .end ());vector <string > words = { "Das", "ist", "ein", "Satz "};string text = sum(words .begin (), words .end ());// " DasisteinSatz "double max_salary = ??Nein!
  140. 140. Die Summe wird noch generischer ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 37 / 60template <class Iter , class T>T sum(Iter v, Iter end , T init) {T s = init;while (v != end) {s = s + *v;v++;}return s;}
  141. 141. Die Summe wird noch generischer ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 37 / 60template <class Iter , class T>T sum(Iter v, Iter end , T init) {T s = init;while (v != end) {s = s + v->salary;v++;}return s;}
  142. 142. Die Summe wird noch generischer ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 37 / 60template <class Iter , class T>T sum(Iter v, Iter end , T init) {T s = init;while (v != end) {s = s + " " + *v;v++;}return s;}
  143. 143. Die Summe wird noch generischer ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 37 / 60template <class Iter , class T>T sum(Iter v, Iter end , T init) {T s = init;while (v != end) {s = max(s,*v);v++;}return s;}
  144. 144. Die Summe wird noch generischer ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 37 / 60template <class Iter , class T>T sum(Iter v, Iter end , T init) {T s = init;while (v != end) {s = ;v++;}return s;}Alles von der Form s = op(s,*v).
  145. 145. Summe XXL: ReduceMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 38 / 60template <class Iter , class T>T sum(Iter v, Iter end , T init) {T s = init;while (v != end) {s = s + *v;v++;}return s;}
  146. 146. Summe XXL: ReduceMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 38 / 60template <class Iter , class T, class Op>T reduce( Iter v, Iter end , T init, Op op) {T s = init;while (v != end) {s = op(s,*v);v++;}return s;}
  147. 147. Was kann reduce?MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 39 / 60vector <employee > staff ;double salaries = reduce (staff .begin (), staff .end (),0.0,[]( double s, employee e){return s + e.salary ;} );
  148. 148. Was kann reduce?MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 39 / 60vector <employee > staff ;double salaries = reduce (staff .begin (), staff .end (),0.0,[]( double s, employee e){return s + e.salary ;} );vector <string > w = { "Das", "ist", "ein", "Satz "};string text = reduce (w.begin (), w.end(), string (),[]( string s, string t){return s + " " + t;} );// " Das ist ein Satz" -> beachte fuehrenden space
  149. 149. Was kann reduce?MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 39 / 60vector <employee > staff ;double salaries = reduce (staff .begin (), staff .end (),0.0,[]( double s, employee e){return s + e.salary ;} );vector <string > w = { "Das", "ist", "ein", "Satz "};string text = reduce (w.begin (), w.end(), string (),[]( string s, string t){return s + " " + t;} );// " Das ist ein Satz" -> beachte fuehrenden spacedouble max_salary =reduce (staff .begin (), staff .end(), ???,[]( double s, employee e){return max(s, e.salary );} );
  150. 150. Was kann reduce?MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 39 / 60vector <employee > staff ;double salaries = reduce (staff .begin (), staff .end (),0.0,[]( double s, employee e){return s + e.salary ;} );vector <string > w = { "Das", "ist", "ein", "Satz "};string text = reduce (w.begin (), w.end(), string (),[]( string s, string t){return s + " " + t;} );// " Das ist ein Satz" -> beachte fuehrenden spacedouble max_salary =reduce (staff .begin (), staff .end(), ???,[]( double s, employee e){return max(s, e.salary );} );Das neutrale Element verfolgt uns!
  151. 151. Wieder ¨Arger mit initMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 40 / 60Wie sieht das richtige init f¨ur das Maximum aus?
  152. 152. Wieder ¨Arger mit initMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 40 / 60Wie sieht das richtige init f¨ur das Maximum aus?F¨ur init muss gelten: max(x,init) == x (f¨ur alle x)
  153. 153. Wieder ¨Arger mit initMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 40 / 60Wie sieht das richtige init f¨ur das Maximum aus?F¨ur init muss gelten: max(x,init) == x (f¨ur alle x)Also init <= x (f¨ur alle x)
  154. 154. Wieder ¨Arger mit initMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 40 / 60Wie sieht das richtige init f¨ur das Maximum aus?F¨ur init muss gelten: max(x,init) == x (f¨ur alle x)Also init <= x (f¨ur alle x)Wie kommen wir an diesen Wert init f¨ur beliebige Typen T?
  155. 155. Wieder ¨Arger mit initMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 40 / 60Wie sieht das richtige init f¨ur das Maximum aus?F¨ur init muss gelten: max(x,init) == x (f¨ur alle x)Also init <= x (f¨ur alle x)Wie kommen wir an diesen Wert init f¨ur beliebige Typen T?Vielleicht hilft std::numeric limits?
  156. 156. Wieder ¨Arger mit initMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 40 / 60Wie sieht das richtige init f¨ur das Maximum aus?F¨ur init muss gelten: max(x,init) == x (f¨ur alle x)Also init <= x (f¨ur alle x)Wie kommen wir an diesen Wert init f¨ur beliebige Typen T?Vielleicht hilft std::numeric limits?template <class T> struct numeric_limits {static T min ();static T max ();...
  157. 157. Wieder ¨Arger mit initMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 40 / 60Wie sieht das richtige init f¨ur das Maximum aus?F¨ur init muss gelten: max(x,init) == x (f¨ur alle x)Also init <= x (f¨ur alle x)Wie kommen wir an diesen Wert init f¨ur beliebige Typen T?Vielleicht hilft std::numeric limits?template <class T> struct numeric_limits {static T min ();static T max ();...Teilweise. numeric limits<T>::min() liefert
  158. 158. Wieder ¨Arger mit initMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 40 / 60Wie sieht das richtige init f¨ur das Maximum aus?F¨ur init muss gelten: max(x,init) == x (f¨ur alle x)Also init <= x (f¨ur alle x)Wie kommen wir an diesen Wert init f¨ur beliebige Typen T?Vielleicht hilft std::numeric limits?template <class T> struct numeric_limits {static T min ();static T max ();...Teilweise. numeric limits<T>::min() liefertWenn T ganzzahlig: Minimalen Wert
  159. 159. Wieder ¨Arger mit initMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 40 / 60Wie sieht das richtige init f¨ur das Maximum aus?F¨ur init muss gelten: max(x,init) == x (f¨ur alle x)Also init <= x (f¨ur alle x)Wie kommen wir an diesen Wert init f¨ur beliebige Typen T?Vielleicht hilft std::numeric limits?template <class T> struct numeric_limits {static T min ();static T max ();...Teilweise. numeric limits<T>::min() liefertWenn T ganzzahlig: Minimalen WertWenn T Fliesskomma: Minimalen positiven Wert
  160. 160. Ein neutrales Element f¨urs Maximum ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 41 / 60vector <int > vi; // ...int maxi = reduce (vi.begin (), vi.end(),std::numeric limits<int>::min(),std :: max );
  161. 161. Ein neutrales Element f¨urs Maximum ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 41 / 60vector <int > vi; // ...int maxi = reduce (vi.begin (), vi.end(),std::numeric limits<int>::min(),std :: max );vector <float > vf; // ...float maxf = reduce (vf.begin (), vf.end(),- std::numeric limits<float>::max(),std :: max );
  162. 162. Ein neutrales Element f¨urs Maximum ...MotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 41 / 60vector <int > vi; // ...int maxi = reduce (vi.begin (), vi.end(),std::numeric limits<int>::min(),std :: max );vector <float > vf; // ...float maxf = reduce (vf.begin (), vf.end(),- std::numeric limits<float>::max(),std :: max );Das ist t¨odlich!
  163. 163. Ein neutrales Element f¨urs MaximumMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 42 / 60Brauchen einheitliche Syntax: uniform limits
  164. 164. Ein neutrales Element f¨urs MaximumMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 42 / 60Brauchen einheitliche Syntax: uniform limitsTyp T Wert v. uniform limits<T>::min()integral std::numeric limits<T>::min()Fliesskomma -std::numeric limits<T>::max()sonstig undefiniert (Anwender)
  165. 165. Ein neutrales Element f¨urs MaximumMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 42 / 60Brauchen einheitliche Syntax: uniform limitsTyp T Wert v. uniform limits<T>::min()integral std::numeric limits<T>::min()Fliesskomma -std::numeric limits<T>::max()sonstig undefiniert (Anwender)template <class T> // C++11 Abkuerzungusing nl = std :: numeric_limits <T>;
  166. 166. Ein neutrales Element f¨urs MaximumMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 42 / 60Brauchen einheitliche Syntax: uniform limitsTyp T Wert v. uniform limits<T>::min()integral std::numeric limits<T>::min()Fliesskomma -std::numeric limits<T>::max()sonstig undefiniert (Anwender)template <class T> // C++11 Abkuerzungusing nl = std :: numeric_limits <T>;Allgemeiner Falltemplate <class T,bool is_spec ,bool is_int >struct uniform_limits { };
  167. 167. Ein neutrales Element f¨urs MaximumMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 42 / 60Brauchen einheitliche Syntax: uniform limitsTyp T Wert v. uniform limits<T>::min()integral std::numeric limits<T>::min()Fliesskomma -std::numeric limits<T>::max()sonstig undefiniert (Anwender)template <class T> // C++11 Abkuerzungusing nl = std :: numeric_limits <T>;Allgemeiner Falltemplate <class T,bool is_spec = nl<T>::is specialized,bool is_int = nl<T>::is integer>struct uniform_limits { };
  168. 168. Ein neutrales Element f¨urs MaximumMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 43 / 60template <class T,bool is_spec = nl <T >:: is_specialized ,bool is_int = nl <T >:: is_integer >struct uniform_limits { };
  169. 169. Ein neutrales Element f¨urs MaximumMotivationTraditionelleAnsaetzeLiftenWie man eineImplementierunggenerisch machtWeg mit doubleWeg mit arrayGenerische SummeNutzungNeutrales ElementReduceReduce undneutrales ElementMax: NeutralesElementReduce wrapupFazitGenerischeProgrammierungFazitGenerische Programmierung 43 / 60template <class T,bool is_spec = nl <T >:: is_specialized ,bool is_int = nl <T >:: is_integer >struct uniform_limits { };Version f¨ur integrale Typentemplate <class T>struct uniform_limits <T, true , true >{ static T min () { return nl <T >:: min (); } };

×