1 Jazyk C++ I Šablony 2 AR 2013/2014 Jazyk C++ I2 Třídy template class TVektor { T *a; int n; static int PocInstanci; public: TVektor(int _n = 0) : n...
Třídy template 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
2
Metody template struct TA { void f1(); void f2(); void f3(); void f4(); // … }; AR 2013/2014
Jazyk C++ I
3
Metody template void TA::f1() { … } // ok template void TA::f2() { … } // ok template void TA::f3() { … } // error
template void TA::f4() { … } // error
AR 2013/2014
Jazyk C++ I
4
Metody template bool TVektor::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
5
Instance template class TA { … }; TA B; // ok TA A; // ok – TA TA<> C; // ok – TA TA D; // error
AR 2013/2014
Jazyk C++ I
6
Vnořené šablony
Složka třídy nebo šablony třídy Vnořená šablonová třída Vnořená šablonová metoda
AR 2013/2014
Jazyk C++ I
7
Vnořené šablony Nemůžou být virtuální metody a destruktory Může jim být konstruktor V případě konstruktoru s jedním parametrem překladač nevytváří kopírovací konstruktor.
Název šablony se může shodovat s názvem obyčejné metody.
AR 2013/2014
Jazyk C++ I
8
Vnořené šablony Šablona metody se použije v případě, že si neodpovídají typy nebo počty formálních a skutečných parametrů. Vnořené šablony nemohou být součástí lokální třídy. Ve vnořené šabloně lze použít formální parametr šablony obklopující třídy, ale ne naopak. AR 2013/2014
Jazyk C++ I
9
Vnořené šablony template struct TA { template struct TB { V z; U z2; V Pricti(V x); };
T x, y; TB b; };
AR 2013/2014
Jazyk C++ I
10
Vnořené šablony template template V TA::TB::Pricti(V x) { z += x; return z; }
AR 2013/2014
Jazyk C++ I
11
Vnořené šablony TA A; A.x = 10; // x je typu int A.b.z = 5.4; // z je typu double //instance vnořené šablony TB //typ int v TA nemá na deklaraci //TB vliv, může být libovolného typu TA::TB B; B.z = 'c'; B.z2 = 5.4; AR 2013/2014
Jazyk C++ I
12
Vnořené šablony template class TVektor { //... template void Assign(InputIterator first, InputIterator last); }; AR 2013/2014
Vnořený typ typového parametru šablony Typovým parametrem šablony může být třída obsahující deklaraci vnořeného typu. Lze použít v šabloně třídy
Překladat kontroluje existenci vnořeného typu už v době, kdy narazí na deklaraci šablony. Potřeba překladači sdělit pomocí klíčového slova typename, že je to typ.
AR 2013/2014
Jazyk C++ I
16
Vnořený typ typového parametru šablony template class TA { typename T::TC b; //... };
AR 2013/2014
Jazyk C++ I
17
Vnořený typ typového parametru šablony template class TA { typedef typename T::TC TCC; TTC b; //... };
AR 2013/2014
Jazyk C++ I
18
Funkce
Pomocí šablon funkce můžeme popsat naráz celou řadu funkcí lišící se například pouze typem parametrů.
AR 2013/2014
Jazyk C++ I
19
Funkce template inline T Max(T a, T b) { return a > b ? a : b; } AR 2013/2014
Jazyk C++ I
20
Instance funkcí Pokud se zavolá funkce, kterou překladač nezná, ale je schopen ji vytvořit ze šablony, vytvoří se její potřebná instance. cout << Max(1, 2); // create Max cout << Max(1.4, 1.5); // create Max<double> cout << Max(1, 'b'); // Error cout << Max(2.2, 1); // Error AR 2013/2014
Jazyk C++ I
21
Instance funkcí Můžeme také explicitně překladači říci, jaký typ má být použit. // bude se volat Max cout << Max(1, 'b'); // bude se volat //Max<double> cout << Max<double>(2.2, 1); AR 2013/2014
Jazyk C++ I
22
Instance funkcí Pokud je skutečný typ uveden jen jako návratový typ, překladač nedokáže v tomto případě vytvořit potřebnou instanci automaticky.
template T f(int i) { return T(i*2); } double b = f(10); // Error double b = f<double>(10); // OK AR 2013/2014
Jazyk C++ I
23
Přetěžování V jednom oboru viditelnosti lze deklaravoat více šablon funkcí se stejným názvem. Stejně lze definovat šablonu funkce a obyčejnou funkci se stejným názvem. Pravidla pro určení, která varianta se bude volat se řídí podobnými pravidly jako u přetěžování obyčejných funkcí.
AR 2013/2014
Jazyk C++ I
24
Přetěžování Pokud má překladač na vybranou, zda zavolat existující obyčejnou funkci nebo vytvořit instanci šablony funkce, Upřednostní obyčejnou funkci. Pokud typy formálních parametrů přesně odpovídají typům skutečných parametrů.
Pokud si typy přesně neodpovídají, ale lze je implicitně konvertovat, dá překladač taktéž přednost obyčejné funkci. AR 2013/2014
Jazyk C++ I
25
Vazba jmen V těle šablony můžeme používat také globální jména typů, proměnných atd., Která jsou v místě deklarace šablony viditelná.
AR 2013/2014
Jazyk C++ I
26
Vazba jmen int i = 10; template inline T GetI() { return i; } int main() { int i = 50; cout << GetI();
return 0; }
AR 2013/2014
Jazyk C++ I
27
Explicitní specializace Pokud je potřeba pro určité skutečné parametry deklarovat speciální verzi šablony, umožňuje to tzv. explicitní specializace.
AR 2013/2014
Jazyk C++ I
28
Explicitní specializace Explicitní specializace lze deklarovat pro: Šablonu obyčejné funkce Šablonu třídy Metody šablonovy třídy Statický atribut šablony třídy Třídu vnořenou do šablony třídy Šablonu vnořenou do jiné šablony třídy Šablonu metody vnořenou do šablony třídy
Explicitní specializace – obyčejné funkce Vypis(10, 12); // OK – call primary template for create instance Vypis(10.0, 12.5); // OK – call explicite specialization Vypis(10, 12.5); // Error
AR 2013/2014
Jazyk C++ I
32
Explicitní specializace – metody šablony třídy template class TVektor { void Vypis(); }; template void TVektor::Vypis() { } //specialization template < > void TVektor<double>::Vypis() { for (int i = 0; i < n; i++) printf("%.1lf ", a[i]); cout << '\n'; };
AR 2013/2014
Jazyk C++ I
33
Explicitní specializace – šablony třídy template<> class TVektor { char* a; public: TVektor() { a = 0; } TVektor(const char* s); ~TVektor() { delete[] a; } //… }; TVektor::TVektor(const char* s) { a = new char[strlen(s)+1]; strcpy(a, s); }
AR 2013/2014
Jazyk C++ I
34
Explicitní specializace – vnořené šablony Musí být uvedeno mimo tělo obklopující šablony třídy. Pokud je pro obklopující šablonu třídy definována explicitní specializace, nemusí již být definována pro vnořenou šablonu. AR 2013/2014
Jazyk C++ I
35
Explicitní specializace – vnořené šablony template struct TA { template struct TB { U z; }; T x; }; template <> template<> struct TA::TB { int z1, z2; }; TA::TB<double> B; B.z = 2.3;
TA::TB C; // instance of explicit specialization TB
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