Jazyk C++ I Šablony AR 2013/2014 Jazyk C++ I
Úvod Zatím známe programovací styly: Strukturované programování, Objektově orientované programovaní. AR 2013/2014 Jazyk C++ I 2
Příklady void Print(const int& value) { cout << value << endl; } AR 2013/2014 Jazyk C++ I 3
Příklady void Print(const int& value) { cout << value << endl; } void Print(const string& value) { cout << value << endl; } AR 2013/2014 Jazyk C++ I 4
Příklady void Print(const int& value) { cout << value << endl; } void Print(const string& value) { cout << value << endl; } void Print(const TA& value) { cout << value << endl; } AR 2013/2014 Jazyk C++ I 5
Příklady class VectorInt { int* _values; // }; AR 2013/2014 Jazyk C++ I 6
Příklady class VectorInt { int* _values; // }; class VectorString { string* _values; // }; AR 2013/2014 Jazyk C++ I 7
Příklady class VectorInt { int* _values; // }; class VectorString { string* _values; // }; class VectorTA { TA* _values; // }; AR 2013/2014 Jazyk C++ I 8
Generické programování Programovací styl založený na vytváření abstraktních vzorů funkcí a tříd. Základem jsou zde šablony (templates). AR 2013/2014 Jazyk C++ I 9
Šablony Šablony jsou podobné makrům v jazyce C. Zpracovávany překladačem. Umožňují najednou popsat celou řadu funkcí lišících se např. pouze typem parametru. Umožňují najednou popsat celou množinu tříd lišících se například jen datovým typem atributů. AR 2013/2014 Jazyk C++ I 10
Šablony Představují vzory pro překladač, který podle ních vygeneruje konkrétní funkce nebo objektové typy. Hovoříme zde o instancích šablony. AR 2013/2014 Jazyk C++ I 11
Příklad template<typename T> void Print(const T* value) { cout << value << endl; } template<typename T> class Vector { T* _values; // }; AR 2013/2014 Jazyk C++ I 12
Deklarace šablony Šablony nelze deklarovat na lokální úrovni uvnitř bloku. Lze je deklarovat uvnitř objektového typu nebo uvnitř šablony objektového typu. Šablony také lze deklarovat na úrovni souboru. AR 2013/2014 Jazyk C++ I 13
Deklarace šablony Syntakticky korektní zápis deklarace šablony: template<parameterslist> declaration parameterlist formální parametry šablony. declaration deklarace nebo definice funkce nebo třídy, definice vnořené třídy, metody objektového typu, statického atributu šablony třídy nebo definice vnořené šablony. AR 2013/2014 Jazyk C++ I 14
Parametry šablony Syntakticky korektní zápis parametrů šablony je: valueparameter class identifier class identifier = typedesignation typename identifier typename identifier = typedesignation template<parameterslist> class identifier template<parameterslist> class identifier = templatename AR 2013/2014 Jazyk C++ I 15
Parametry šablony template<class T = int> class TA; template<class T> class TA { }; // ok template<class T> class TB; template<class T = int> class TB { }; // ok template<class T = int> class TC; template<class T = int> class TC { }; // error AR 2013/2014 Jazyk C++ I 16
Parametry šablony template<class T, T hodnota, class U = T> class TA { }; AR 2013/2014 Jazyk C++ I 17
Typové parametry Typové parametry lze uvést pomocí klíčových slov class a typename. Ekvivalentní Skutečným parametrem je potom označení typu. Nesmí jim být ale lokální třída. template<class T, class V = int> class TA; template<typename T, typename V = int> class TA; AR 2013/2014 Jazyk C++ I 18
Hodnotové parametry Deklarace obdobně jako u funkcí formální parametry. Hodnotový parametr musí být jedním z následujících typů: Celočíselný Výčtový Ukazatel na objekt Reference na objekt Ukazatel na funkci Třídní ukazatel Veškeré hodnotové parametry šablony se chovají jako konstanty. AR 2013/2014 Jazyk C++ I 19
Hodnotové parametry Celočíselný Skutečný parametrem je celočíselný konstantní výraz. template<class T, int i> class TA { }; TA<double, 10*5> A; Výčtový Skutečným parametrem je celočíselný konstantní výraz, který má za výsledek daný výčtový typ. enum TB { b1, b2, b3 }; template<class T, TB b> class TA { }; TA<int, b2> A; AR 2013/2014 Jazyk C++ I 20
Hodnotové parametry Ukazatel na objekt Skutečným parametrem je konstatní výraz, který představuje adresu pojmenovaného objektu s paměťovou třídou extern. Nelze použít adresu prvku pole. Reference na objekt Skutečným parametrem je l-hodnota představující pojmenovaný objekt s paměťovou třídou extern. AR 2013/2014 Jazyk C++ I 21
Hodnotové parametry Ukazatel na funkci Skutečným parametrem je funkce s externím linkováním. template <class T, T (*f)(t) > class TA {... }; int f(int x) {... } TA<int, f> A; Třídní ukazatel Skutečným parametrem je konstanta představující adresový výraz, který představuje adresu pojmenované složky třídy. struct TB { int x, y; } template <class T, class U, T U::*u> class TA {... }; TA<int, TB, &TB::x> A; AR 2013/2014 Jazyk C++ I 22
Šablonové parametry Název existující šablony třídy může být parametrem pro jinou šablonu. AR 2013/2014 Jazyk C++ I 23
Šablonové parametry template <class T, template<class U> class W> class TA { W<T> a, b; public: TA(W<T> _a, W<T> _b) : a(_a), b(_b) {} }; template <class T> struct TB { T x, y; }; TB<int> b1 = { 10, 20 }, b2 = { 30, 40 }; TA<int, TB> A(b1, b2); AR 2013/2014 Jazyk C++ I 24
Třídy Šablony pro objektové typy, tj. pro třídy, struktury nebo unie, může obsahovat stejné druhy složek jako objektový typ. Součástí šablony mohou být vložené, statické a virtuální metody, vnořené objektové typy apod. AR 2013/2014 Jazyk C++ I 25
Třídy template <class T> class TVektor { T *a; int n; static int PocInstanci; public: TVektor(int _n = 0) : n(_n) { a = new T[n]; PocInstanci++; } ~TVektor() { delete[] a; PocInstanci--; } T& operator[](int index) { return a[index]; } bool operator == (const TVektor& t); static int GetPocInstanci() { return PocInstanci; } }; AR 2013/2014 Jazyk C++ I 26
Metody Jestliže metody nejsou definovány přímo v těle šablony, musí být definovány jako šablony. Šablona této metody potom musí obsahovat stejné formální parametry jako šablona její třídy, a to ve stejném pořadí. Jména formálních parametrů se potom mohou lišit. Jména metod musí být kvalifikována jmenovkou třídy, za kterou jsou v lomených závorkách jména formálních parametrů ve stejném pořadí. AR 2013/2014 Jazyk C++ I 27
Metody template<class T1, class T2, int z> struct TA { void f1(); void f2(); void f3(); void f4(); // }; AR 2013/2014 Jazyk C++ I 28
Metody template<class T1, class T2, int z> void TA<T1, T2, z>::f1() { } // ok template<class T2, class T1, int z> void TA<T2, T1, z>::f2() { } // ok template<class T1, class T2, int z> void TA<z, T2, T1>::f3() { } // error template<class T1, int z, class T2> void TA<T1, z, T2>::f4() { } // error AR 2013/2014 Jazyk C++ I 29
Metody template<class T> bool TVektor<T>::operator == (const TVektor& t) { if (n!= t.n) return false; for (int i = 0; i < n; i++) { if (a[i]!= t.a[i]) return false; } return true; } AR 2013/2014 Jazyk C++ I 30
Statické atributy Statické atributy je nutno definovat jako šablony. Šablony statického atributu se řídí stejnými pravidly jako šablony metod. template<class T> class TVektor { }; template<class T> int TVektor<T>::PocInstanci = 0; AR 2013/2014 Jazyk C++ I 31
Vnořené třídy Vnořené třídy, které jsou definované mimo obklopující šablonu třídy, se musí definovat jako šablony. Opět se řídí stejnými pravidly jako šablony metod. AR 2013/2014 Jazyk C++ I 32
Vnořené třídy template<class T> struct TA { struct TB; // }; template<class T> struct TA<T>::TB { T z; T& Pricti(T _z); }; template<class T> T& TA<T>::TB::Pricti(T _z) { z += _z; return z; } TA<int>::TB B; // instance of nested class AR 2013/2014 Jazyk C++ I 33
Instance Dosazením skutečných parametrů namísto formálních v šabloně třídy vzniká instance šablony třídy podle této šablony. Jméno se pak skládá ze jména šablony a ze skutečných parametrů v lomených závorkách. AR 2013/2014 Jazyk C++ I 34
Instance template <class T = int, int n = 10> class TA { }; TA<char, 12> B; // ok TA<char> A; // ok TA<char, 10> TA<> C; // ok TA<int, 10> TA D; // error AR 2013/2014 Jazyk C++ I 35
Instance TVektor<int> A(10), B(20); TVektor<double> C(10); TVektor< TVektor<int> > D(10); cout << TVektor<int>::GetPocInstanci() << endl; cout << TVektor<double>::GetPocInstanci() << endl; AR 2013/2014 Jazyk C++ I 36
Instance Při vytváření instance šablony se generují virtuální metody instance šablony třídy. Překladač zároveň vytvoří ty instance metod a statických atributů, které jsou v programu použity. Pokud mají dvě instance šablony třídy skutečné parametry stejného typu, hodnotové parametry stejné hodnoty a šablonové typy se odkazují na stejnou šablonu, jsou tyto instance stejného typu. AR 2013/2014 Jazyk C++ I 37
Instance template<class T, int n = 7> struct TA { }; typedef unsigned int uint; TA<unsigned, 5+2> A; TA<uint, 10-3> B; TA<uint> C; TA<uint, 10> D; AR 2013/2014 Jazyk C++ I 38
Zdroje PRATA, Stephen. Mistrovství v C++. 3. aktualiz. vyd. Překlad Boris Sokol. Brno: Computer Press, 2007, 1119 s. ISBN 978-80-251-1749-1. cplusplus.com AR 2013/2014 Jazyk C++ I 39