Innehåll. 1 Funktionsmalllar. 2 Klassmallar. struct Name { string s; //... }; const Name & minimum ( const Name & a, const Name & b) { if(a.s < b.

Relevanta dokument
Innehåll. Parametriserade typer. Klassmallar. Klassmallen Vektor Konstructor med std::initializer_list. Klassmallen Vektor Medlemsfunktioner

Innehåll. Exceptionella händelser (exceptions, undantag ) Felhantering Tre nivåer av felhantering: Nivå 2: exceptions (eller returvärde)

Innehåll. 1 Funktionsmallar. 2 Pekare och konstanter. 3 Typomvandlingar. struct Name { string s; //... };

Programmering i C++ EDA623 Mallar. EDA623 (Föreläsning 12) HT / 29

Innehåll. 1 Kort om dynamisk polymorfism. 2 Arv i C++ 3 Multipelt arv. 4 Något om statisk polymorfism. class Container {

Innehåll. Pekaren this Självreferens. Klasser Resurshantering, representation. Överlagring av operatorer. Överlagring av operatorer

Innehåll. Typomvandlingar (casting) Implicita Typomvandlingar. Typomvandlingar (type casts) Explicita, namngivna typomvandlingar (C++-11)

Tentamen EDAF30 Programmering i C++

2D1387, Programsystemkonstruktion med C++ 01/02 1

Innehåll. Pekare Exempel

Tentamen EDAF30 Programmering i C++

Programmering i C++ EDA623 Arv. EDA623 (Föreläsning 6) HT / 42

Innehåll. Pekare Exempel

Inlämningsuppgift, EDAF30, 2016

Innehåll. Pekare. Datatyper Pekare, Arrayer och Referenser. Pekare Syntax. Pekare Syntax, operatorer. 4. Standard-containers. Pekare och arrayer

Inlämningsuppgift, EDAF30, 2018

Generell (template) programmering. Effektiv C++ Slutliga tips Genomgång av gammal tenta. Daniel Aarno Allt som fungerar som x ÄR x

Tentamen EDAF30 Programmering i C++

TDIU01 Programmering i C++

Innehåll. Klasserna vector och deque

Innehåll. 1 volatile. 2 Kuriositeter. 3 Klasser och arv. 4 Råd och tumregler. 5 Mer om standard-containers. Trigraphs

TDIU20 - Objektorienterad programmering i c++ - föreläsning 4

Generiska konstruktioner. Kursbokens kapitel 13

Innehåll. Konstruktorer vid arv Regler för basklassens konstruktor. Konstruktorer vid arv. Konstruktorer vid arv. Konstruktorer vid arv

Tommy Färnqvist, IDA, Linköpings universitet

Innehåll. Resurshantering. Resource handles. Minnesallokering. Minnesallokering Exempel: allokering på stacken. 6. Resurshantering

TDIU01 - Programmering i C++, grundkurs

Innehåll. Typomvandlingar (casting) Implicita Typomvandlingar. Typomvandlingar (casting) Implicita Typomvandlingar

Innehåll. EDAf30: Programmering i C++, 7.5 hp. EDAf30: Programmering i C++, 7.5 hp Viktiga skillnader mot Java

Operatoröverlagring. endast operatorsymboler definierade i C++ kan överlagras = += -= *= /= %= ^= &= = <<= >>= < > <= >= ==!= && > ->*, [ ] ( )

Algoritmbiblioteket (STL) Designstrategi Generiska algoritmer som fungerar på godtyckliga samlingsdatatyper, vilka har iteratorer.

Programmering i C++ EDA623 Objektorienterad programutveckling. EDA623 (Föreläsning 5) HT / 33

Innehåll. Introduktion till objektorientering. OOP (objektorienterad programmering) Objekt, instanser, klasser

Innehåll. Användardefinierade typer. Användardefinierade typer Kategorier. Konstruktorer. Konstruktorer Två sätt att skriva initiering av medlemmar

Del3 Klassanvändning, operatorer och pekare Ämnesområden denna föreläsning:

Programmering i C++ EDA623 Mer om klasser. EDA623 (Föreläsning 6) HT / 26

Intro till standardbiblioteket. Eric Elfving

Tillämpad programmering

TDIU01 - Programmering i C++, grundkurs

Programsystemkonstruktion med C++: Övning 2. Karl Palmskog september 2010

DAT043 - föreläsning 8

Tentamen *:85/2I4123 C

Föreläsning 7 Innehåll. Rekursion. Rekursiv problemlösning. Rekursiv problemlösning Mönster för rekursiv algoritm. Rekursion. Rekursivt tänkande:

Innehåll. Resource handles. Resurshantering. Minnesallokering. Minnesallokering Exempel: allokering på stacken. 7. Resurshantering, Felhantering

Innehåll. 1 Deklarationer, scope och livstid. 2 Användardefinierade typer. 4 In- och utmatning. 5 Operatoröverlagring. 6 namnrymder (namespace)

Lektionsuppgifter. TDDI14 Objektorienterad programmering. Lektionsplanering Lektion Lektion Lektion

DD2387 Programsystemkonstruktion med C++ Tentamen 1 Torsdag 7 januari 2016, 14:00-18:00

Tentamen EDAF30 Programmering i C++

Innehåll. 1 Typdeklarationer och typomvandling 2 Resurshantering. 3 Objektorientering, kort repetition. 4 Klasser

Övriga byggstenar. Övriga byggstenar. Några tips under programutveckling. Beroenden Pekare till funktioner Typkonvertering

TDDC76 - Programmering och Datastrukturer

TDIU01 - Programmering i C++, grundkurs

TDDC76 - Programmering och Datastrukturer

Kapitel 4 - Mallar. Kapitel 4. Introduktion till mallar STL. 2D1387 Programsystemkonstruktion med C++ 1

Kapitel 4. Funktionsmallar. Mallar. Introduktion till mallar STL

Kapitel 4. Funktionsmallar. Mallar. Introduktion till mallar STL

Innehåll. 1 Deklarationer, scope och livstid. 2 Användardefinierade typer. 4 Operatoröverlagring. 5 In- och utmatning. 6 namnrymder (namespace)

Innehåll. Pekare Syntax

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

Innehåll. Datatyper Pekare, Arrayer och Referenser. Pekare. Pekare Syntax. Pekare Syntax, operatorerna * och & 5. Pekare och arrayer. Algoritmer.

Tentamen i Objektorienterad Programmering 5p, Au, D, Fri, Pr,

Symboliska konstanter const

Introduktion till arv

TDDC30. Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Erik Nilsson, Institutionen för Datavetenskap, LiU

Collections Collections "Envisa" objekt Klasserna Bofstream och Bifstream Definition av metoder i klasserna Bifstream och Bofstream Klassen Streng

Tentamen EDAF30 Programmering i C++

DD2387 Programsystemkonstruktion med C++ Tentamen 2

Programmering i C++ EDA623 Containerklasser och algoritmbibliotek. EDA623 (Föreläsning 10) HT / 33

Objektorienterad programmering i Java, datastrukturer och algoritmer. Föreläsning 4 Jonas Lindgren, Institutionen för Datavetenskap, LiU

Tentamen C++-programmering

2D1387 Programsystemkonstruktion med C++ Laboration 1: Grundläggande C++ 31 augusti 2005

Det finns många flaggor till g++,

Tentamen i TDP004 Objektorienterad Programmering Lösningsförslag

C++ - En introduktion

Den som bara har en hammare tror att alla problem är spikar

Högskolan Dalarna sid 1 av 5 Data-avdelningen Hans-Edy Mårtensson

Användning av typeid. Operatorerna typeid och. Filen typeinfo.h måste inkluderas. typeid

TDDE10 m.fl. Objektorienterad programmering i Java Föreläsning 6 Erik Nilsson, Institutionen för Datavetenskap, LiU

Datatyper och kontrollstrukturer. Skansholm: Kapitel 2) De åtta primitiva typerna. Typ Innehåll Defaultvärde Storlek

TDDC76 - Programmering och Datastrukturer

TDIU01 - Programmering i C++, grundkurs

Programmering i C++ EDAF30 Dynamiska datastrukturer. EDAF30 (Föreläsning 11) HT / 34

Programmering A. Johan Eliasson

Programsystem konstruktion med C++ (2D1387) Innehåll. övning 2 klasser och arv

4. Standard-containers. Strömmar och filer

TDDC76 Programmering och datastrukturer

7 Templates och Exceptions

TDDC76 - Programmering och Datastrukturer

EDAf30: Programmering i C++, 7.5 hp. EDAf30: Programmering i C++, 7.5 hp Administration. EDAf30: Programmering i C++, 7.5 hp Obligatoriska moment

Programmering i C++ EDA623 Dynamiska datastrukturer. EDA623 (Föreläsning 11) HT / 31

Föreläsning 4 Innehåll. Abstrakta datatypen lista. Implementering av listor. Abstrakt datatypen lista. Abstrakt datatyp

2D1387, Programsystemkonstruktion med C++ Johnny Bigert, Kursens hemsida:

I STONE. I Variabler, datatyper, typkonvertering. I Logiska och matematiska uttryck. I Metoder-returvärde och parametrar. I Villkorssatser if/else

Repetition C-programmering

Föreläsning 4 Innehåll

Föreläsning 3. Stack

TDDI14 Objektorienterad programmering

Tillämpad programmering

Föreläsning 9 Innehåll

Objektorientering - Arv och polymorfi. Eric Elfving Institutionen för datavetenskap

Transkript:

Innehåll EDAF30 Programmering i C++ Generisk programmering med templates (mallar) Sven Gestegård Robertz Datavetenskap, LTH 2015 1 Funktionsmalllar 2 Generisk programmering med templates (mallar) 2/1 Generisk programmering Templates (mallar) Använder typparametrar för att skriva mer generella klasser och funktioner Slipper manuellt skriva en ny klass/funtion för varje datatyp som ska hanteras statisk polymorfism En mall instansieras av kompilatorn för typer den används för varje instans är en separat klass/funktion vid kompilering: ingen kostnad vid exekvering Exempel: Vanliga minimifunktionen template < class T> const T& min(const T& a, const T& b) if (a < b) return a; else return b; Kan instansieras för alla typer som har operatorn < Generisk programmering med templates (mallar) 3/31 Funktionsmalllar Generisk programmering med templates (mallar) 4/31 Överlagring med vanlig funktion Instansiering av funktionsmallar sker i vissa fall automatiskt t.ex. vid utskrift: double x = 7.0, y = 5.0; long m = 5, n = 7; //... cout << min (x, y) << endl ; cout << min (m, n) << endl ; // Blandat funkar inte ( ingen casting görs!) cout << min (m, y) << endl ; // För att forcera casting blir man explicit cout << min <double >(m, y) << endl ; En explicit instans av en funktionsmall är en vanlig funktion implicit typkonvertering av argument struct Name string s; //... ; Överlagring för Name& const Name & minimum ( const Name & a, const Name & b) if(a.s < b.s) return a; else return b; Funktionsmalllar Generisk programmering med templates (mallar) 5/31 Funktionsmalllar Generisk programmering med templates (mallar) 6/31

Funktionsmall för minsta elementet i en array kan överlagras template < typename T> T& min_element (T a[], size_t n) cout << "[min_element <"<<typeid (T). name ()<<"[] >]\n"; size_t idx = 0; for ( size_t i = 1; i < n; ++i) if(a[i] < a[ idx ]) idx = i; return a[ idx ]; (kompilatorn härleder typparametern T) int a[] 3,5,7,6,8,5,2,4; Generalisering: överlagra min_element för fler datastrukturer int ma = min_element (a, sizeof (a)/ sizeof (int )); Funktionsmalllar Generisk programmering med templates (mallar) 7/31 Funktionsmalllar Generisk programmering med templates (mallar) 8/31 Funktionsmall för minsta elementet i iterator-par Funktionsmall för minsta elementet i en vector<t> template <typename FwdIterator > ForwardIterator min_element ( FwdIterator start, FwdIterator end) if( start == end ) return end ; ForwardIterator res = start ; auto it = start ; while (++ it!= end ) if (* it < * res ) res = it; return res ; Standardalgoritmerna är templates int a[] 3,5,7,6,8,5,2,4; int ma2 = * min_element (begin (a), end (a )); int ma3 = * min_element (a+2,a +4); Detta är en version av std::min_element Parametriserad på element-typen för vector template < typename T> T& min_element (vector <T>& c) if(v. begin ()==v.end ()) throw std :: range_error ("empty vector "); return * min_element (v.begin (), v.end ()); vector <int > v3,5,7,6,8,5,2,4; int mv2 = min_element (v); vector <int > v3,5,7,6,8,5,2,4; int mv = * min_element (v.begin (), v.end ()); Funktionsmalllar Generisk programmering med templates (mallar) 9/31 Funktionsmalllar Generisk programmering med templates (mallar) 10/31 Funktionsmall för minsta elementet i en container Variant som kan användas för en godtycklig klass som har begin() och end() har en typedef som definierar namnet value_type (detta uppfylls av alla standard-containers) template <class Container > typename Container :: value_type & min_element ( Container & c) if(c. begin ()==c. end ()) throw std :: range_error ("empty container "); return * min_element (c.begin (), c.end ()); Kan även deklareras med två typ-parametrar: template <typename Container, typename T = typename Container :: value_type > T& min_element ( Container & c) Funktionsmall för minsta elementet i en container Variant som kan användas för en godtycklig klass-template som har elementtypen (T) som typparameter (kan ha fler: (...) har begin() och end() template <typename T, template <typename... > class CONT > T& min_element (CONT <T>& c) if(c. begin ()==c.end ()) throw std :: range_error ("empty container "); return * min_element (c.begin (), c.end ()); Funktionsmalllar Generisk programmering med templates (mallar) 11/31 Funktionsmalllar Generisk programmering med templates (mallar) 12/31

Funktionsmall för minsta elementet i en array minsta elementet i nånting man kan iterera över Trick: värdeparameter för arrayens storlek, och inferens template < typename T, size_t N> T& min_element (T (&a)[n]) size_t idx = 0; for ( size_t i = 1; i < N; ++i) if(a[i] < a[ idx ]) idx = i; return a[ idx ]; int a[] 3,5,7,6,8,5,2,4; int ma4 = min_element (a); Här vet kompilatorn storleken på a[] och fyller i mall-parametern N int a[] 3,5,7,6,8,5,2,4; int & ma = min_element (a); vector <int > v3,5,7,6,8,5,2,4; int & mv = min_element (v); deque <int > dv. begin (), v.end (); int & md = min_element (d); string s" kontrabasfiol "; char & ms = min_element (s); Funktionsmalllar Generisk programmering med templates (mallar) 13/31 Funktionsmalllar Generisk programmering med templates (mallar) 14/31 std::min_element för typer som inte har < Överlagring med en template-parameter: LESS (en egenskapsklass) template <class IT, class LESS > IT min_element (IT first, IT last, LESS cmp ) IT m = first ; for (IT i = ++ first ; i!= last ; ++i) if (cmp (*i, *m)) m = i; return m; LESS måste ha operator() och typerna måste stämma, t ex: class Str_Less_Than bool operator () ( const char *s1, const char *s2) return strcmp (s1, s2) < 0; ; std::min_element för typer som inte har < Exempel på användning med stränglista: list < const char *> tl = "hej", "du", " glade " ; Str_Less_Than lt; // funktionsobjekt cout << * min_element (tl.begin (), tl.end (), lt ); Str_Less_Than-objektet kan skapas direkt i parameterlistan: cout << * min_element (tl.begin (), tl.end (), Str_Less_Than ()); (C++11) lambda: anonymt funktions-objekt auto cf= []( const char * s, const char * t) return strcmp (s,t) <0;; cout << * min_element (tl.begin (), tl.end (), cf ); Funktionsmalllar Generisk programmering med templates (mallar) 15/31 Funktionsmalllar Generisk programmering med templates (mallar) 16/31 Container från f7 Containerklasserna vector, deque och list utgör exempel på klasser med typparametrisering eller klassmallar Kompilatorn genererar utgående från en sådan klassmall alla olika typer av klasser som behövs beroende på aktuell typ insatt som typparameter Slipper manuellt skriva en ny klass för varje enskild komponentdatatyp för att implementera en viss sammansatt datastruktur Klasser kan parametriseras Exempel: container-klasser i standardbiblioteket std::vector std::deque std::list class Container virtual int size () const =0; virtual int& operator []( int o) =0; virtual ~ Container () virtual void print () const =0; ; class Vektor : public Container Vektor ( int l = 10) :p new int [l],szl ~ Vektor () delete [] p; int size () const override return sz ; int & operator []( int i) override return p[i]; virtual void print () const override ; int *p; int sz; ; generalisera till godtycklig elementtyp Generisk programmering med templates (mallar) 17/31 Generisk programmering med templates (mallar) 18/31

Parametriserad Container och Vektor class Container virtual size_t size () const =0; virtual T& operator []( size_t o) =0; virtual ~ Container () virtual void print () const =0; ; class Vektor : public Container <T> Vektor ( size_t l = 10) :pnew T[l],szl ~ Vektor () delete [] p; size_t size () const override return sz ; T& operator []( size_t i) override return p[i ]; virtual void print () const override ; T *p; size_t sz; ; Generisk programmering med templates (mallar) 19/31 Definition av medlemsfunktioner void Vektor <T>:: print () const for ( size_t i = 0; i!= sz; ++i) cout << p[i] << " "; cout << endl ; Specialisering av mallen för typen Foo: (medlemmar i en klassmall är mallar) template <> void Vektor <Foo >:: print () const for ( size_t i = 0; i!= sz; ++i) cout << "Foo(" <<p[i].x << ") "; cout << endl ; Fungerar för alla typer som har operator<< men inte för element av typ struct Foo int x; ; Foo(int d=0) :xd Generisk programmering med templates (mallar) 20/31 class Tree Tree () : root ( nullptr ) Tree (D d) : root new Node (d ) ~ Tree () delete root ; bool empty () const return root == nullptr ; D& value () const check (); return root ->data ; Tree & l_child () const check (); return root ->left ; Tree & r_child () const check (); return root ->right ; void insert (D d); D* find (D d); class Node... Node * root ; void check () const if( empty ()) throw range_error (" Empty tree "); ; Node som inre klass Nodklassen som inre klass class Tree //... class Node friend class Tree <D>; D data ; Tree <D> left ; Tree <D> right ; Node (D d) : data d ~ Node () ; ; Generisk programmering med templates (mallar) 21/31 Generisk programmering med templates (mallar) 22/31 : Medlemsfunktioner i en klassmall är funktionsmallar Ett träd med heltal void Tree <D>:: insert (D d) if( empty ()) root = new Node (d); else if( d< value ()) l_child (). insert (d); else r_child (). insert (d); D* Tree <D>:: find (D d) if( empty ()) return nullptr ; else if(d== value ()) return & value (); else if(d < value ()) return l_child (). find (d); else return r_child (). find (d); void test_tree () Tree <int > t; t. insert (17); t. insert (11); t. insert (22); t. insert (19); try_find (t,22); try_find (t,19); try_find (t,23); 22 found 19 found 23 not found Hjälpfunktion: void try_find (Tree <T>& t, const T& v) auto res = t. find (v); if(res) cout << v << " found \n"; else cout << v << " not found \n"; Generisk programmering med templates (mallar) 23/31 Generisk programmering med templates (mallar) 24/31

Använda trädet för Person-objekt struct Person string pnr ; string name ; Person ( string pn, string n) :pnr pn,name n ; Tree <Person > ps; ps. insert ( Person ("121110-1516 ", "Kalle " )); /Users /sven /work1 / kurser /cpp / test_templates.cpp : In instantiation of void Tree <D>:: insert (D) [ with D = Person ] : test_templates. cpp 699 col 45 required from here test_templates. cpp 606 col 16 error no match for operator < ( operand types are Person and Person ) else if( d<value ())...... Generisk programmering med templates (mallar) 25/31 Lösning: använd egenskapsklass för att ge jämförelseoperationerna Lägg till en typparameter till trädmallen template <class D, class E> class Tree using Comp = E; // Lokalt namn för typparametern // samma som förut class Node friend class Tree <D>; D data ; Tree <D,E> left ; Tree <D,E> right ; Node (D d) : data d ~ Node () ; // samma som förut ; Generisk programmering med templates (mallar) 26/31 med egenskapsklass Medlemsfunktionerna använder komparator-klassen template <class D, class E> D* Tree <D,E>:: find (const D& d) if( empty ()) return nullptr ; else if( Comp :: equal (d, value ()) ) // eller E:: equal return & value (); else if(e:: less_than (d,value ()) ) // eller Comp :: less_than return l_child (). find (d); else return r_child (). find (d); Generisk programmering med templates (mallar) 27/31 med egenskapsklass Comparator-klassmall för vanliga typer struct Comparator static bool less_than (T l, T r) return l < r; static bool equal (T l, T r) return l == r; ; Specialisering av Comparator för Person template <> // specialisering -> ingen parameter struct Comparator<Person > // Ange typen explicit här static bool less_than ( Person l, Person r) return l.pnr. compare (r.pnr) < 0; static bool equal ( Person l, Person r) return l.pnr. compare (r.pnr) == 0; ; Generisk programmering med templates (mallar) 28/31 Lägg till en defaultparameter för Comparator Kompilatorn väljer Comparator<D> template <class D, class E=Comparator <D>> class Tree // samma som fö rut ; Nu fungerar: Tree <char > tc; tc. insert ( A ); tc. insert ( c ); try_find (tc, a ); try_find (tc, c ); Tree <Person > ps; ps. insert ( Person ("131211-1233 ", "Lisa " )); ps. insert ( Person ("010203-9876 ", "Nisse ")); try_find (ps, Person (" 010203-9876 ", " Vem " )); Mallar, kommentarer Mallar har parametrar typ-parametrar: deklareras med class eller typename värde-parametrar: deklareras som vanligt, t ex int N Kompilatorn behöver hela mallen för att kunna instansiera den den ska ligga i header-filen (om andra ska inkludera den) Överlagring: Funktioner kan övelagras funktionsmallar kan överlagras Klasser kan inte övelagras klassmallar kan inte överlagras Specialisering: kan specialiseras partiellt eller fullständigt kan bara specialiseras fullständigt, men Specialiseringar överlagras inte Ofta bättre/tydligare att överlagra med en vanlig funktion (inte mall) än att specialisera Generisk programmering med templates (mallar) 29/31 Generisk programmering med templates (mallar) 30/31

Vi har talat om Funktionsmall för minsta elementet i en container parametriserade funktioner parametriserade klasser Nästa föreläsning: de sista pusselbitarna namespace union bit-operatorer bit-fält Kommentarer och tips Variant för godtycklig klass som har begin() och end() template <class Container > auto min_element ( Container & c) -> decltype (*c.begin ()) if(c. begin ()==c.end ()) throw std :: range_error ("empty container "); return * min_element (c.begin (), c.end ()); Trailing return type (C++11) decltype : typoperator som ger typen av ett uttryck (&) om Container är vector<int> blir returtypen int& : deque <int > d5,3,1,2; int md = min_element (d); string s" kontrabasfiol "; char & ms = min_element (s); Generisk programmering med templates (mallar) 31/31 Generisk programmering med templates (mallar) 32/31