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 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
7
Vnořené šablony template template V TA::TB::Pricti(V x) { z += x; return z; }
AR 2013/2014
Jazyk C++ I
8
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
9
Vnořené šablony template class TVektor { //... template void Assign(InputIterator first, InputIterator last); }; AR 2013/2014
Parciální specializace šablon Poskytuje alternativní definici k primární definici šablony pro určité druhy parametrů.
AR 2013/2014
Jazyk C++ I
22
Parciální specializace šablon Primární šablona musí mít alespoň informativní deklaraci před deklaracemi parciálních specializací této šablony. Každá parciální specializace šablony představuje odlišnou šablonu musí být kompletně definovaná.
Může obsahovat jiné složky, než které obsahuje primární šablona. AR 2013/2014
Jazyk C++ I
23
Parciální specializace šablon Parciálně specializované deklarace se od primární deklarace liší Za jménem šablony následují v lomených závorkách formální parametry, které určují způsob specializace.
Parametry mohou mít odlišné názvy než formální parametry primární šablony
AR 2013/2014
Jazyk C++ I
24
Parciální specializace šablon template class TA { };
//#1
template class TA { };
//#2
template class TA { };
//#3
template class TA { };
//#4
template class TA { };
//#5
AR 2013/2014
Jazyk C++ I
25
Parciální specializace šablon template class TA { }; template class TA { }; template class TA { }; template class TA { }; template class TA { }; TA
AR 2013/2014
1> a1; ???
Jazyk C++ I
26
Parciální specializace šablon template class TA { }; template class TA { }; template class TA { }; template class TA { }; template class TA { }; TA
AR 2013/2014
1> a2; ???
Jazyk C++ I
27
Parciální specializace šablon template class TA { }; template class TA { }; template class TA { }; template class TA { }; template class TA { }; TA a4; ???
AR 2013/2014
Jazyk C++ I
28
Parciální specializace šablon template class TA { }; template class TA { }; template class TA { }; template class TA { }; template class TA { }; TA a3; ???
AR 2013/2014
Jazyk C++ I
29
Parciální specializace šablon template class TA { }; template class TA { }; template class TA { }; template class TA { }; template class TA { }; TA a5;
AR 2013/2014
???
Jazyk C++ I
30
Parciální specializace šablony Složky jako metody, statické atributy, vnořené třídy a šablony definované mimo tělo šablony, musí obsahovat stejný seznam formálních parametrů Stejný seznam specializovaných parametrů
Explicitní vytvoření instance Překladači můžeme přikázat, aby vytvořil instanci šablony, aniž by se hned použila. Lze provést pro šablony funkcí, tříd, metod a statických atributů.
AR 2013/2014
Jazyk C++ I
40
Explicitní vytvoření instance Pro explicitně vytvořené instance šablony třídy překladač ihned vytvoří všechny její metody, statické atributy, a to i když nejsou v programu použity. Stanou se součástí souboru *.obj a *.exe. U dalších typů šablon je to obdobné.
AR 2013/2014
Jazyk C++ I
41
Explicitní vytvoření instance Syntakticky korektní zápis explicitního vytvoření instance šablony je: template declaration Za deklaraci se uvádí v lomených závorkách skutečné parametry šablony. Výjimkou jsou šablony funkce, u kterých překladač umí odvodit koncové parametry.
AR 2013/2014
Jazyk C++ I
42
Explicitní vytvoření instance Explicitní vytvoření instance šablony Tvektor pro typ int. template class TVektor; Nevytváří se ale instance vnořených šablon (tříd a metod). Nevytvoří se tedy instance metod! AR 2013/2014
Jazyk C++ I
43
Explicitní vytvoření instance Potřeba vytvoření explicitních instancí metod template void TVektor::assign(int*, int*); template TVektor::TVektor(int*, int*);
AR 2013/2014
Jazyk C++ I
44
Explicitní vytvoření instance Explicitně lze vytvořit i instance jednotlivých metod a statických atributů bez nutnosti tvořit explicitně instanci celé třídy. template int TVektor<double>::PocInstanci;
AR 2013/2014
Jazyk C++ I
45
Přátelé Přítelem třídy nebo šablony třídy může být:
Obyčejná funkce, Jiná třída, Šablona obyčejné funkce, Šablona jiné třídy, Specializace šablony jiné třídy, Specializace šablony jiné třídy.
AR 2013/2014
Jazyk C++ I
46
Přátelé Pokud má být přítelem šablony třídy TA obyčejná funkce, tak zpravidla jeden z jejích argumentů je typu reference nebo ukazatel na šablonu třídy TA. V takovém případě se jedná o šablonu obyčejné funkce, která má jako formální šablonové parametry formální parametry šablony třídy TA. AR 2013/2014
Jazyk C++ I
47
Přátelé template class TA; template void f2(TA&); template class TB; template class TA { friend void f1(TA&); friend void f2(TA&); template friend void f3(TA&, U); friend class TB; template friend class TC; T x; public: TA(T _x) : x(_x) {} };
AR 2013/2014
Jazyk C++ I
48
Přátelé void f1(TA A) { A.x = A.x; } template void f2(TA& A) { A.x += 2; } template void f3(TA& A, U u) { A.x += static_cast(u); } TA A1(2); TA A2(10.5); f1(A); //OK f1(A2); //ERROR
AR 2013/2014
Jazyk C++ I
49
Přátelé template void f2(TA& A) { A.x += 2; }
Obyčejná funkce f2 včetně jejich explicitních specializaci je přítelem šablony třídy TA. Takto uvedená deklarace spřátelené šablony funkce vyžaduje deklaraci prototypu šablony funkce f2 před definicí šablony třídy TA. Protože v tomto prototypu je uvedena šablona TA, musí být před ním uvedena informativní deklarace šablony třídy TA. Šablona funkce f2 má jeden formální šablonový parametr T, který je identický s formálním parametrem T šablony třídy TA.
Přítelem instance typu TA je instance šablony funkce f2, která má tvar:
void f2(TA&); f2(A); f2(A2);
AR 2013/2014
// A.x = 4 // A2.x = 7
Jazyk C++ I
50
Přátelé Šablonu funkce f2 lze jako přítele šablony třídy TA deklarovat pomocí následujícího způsobu: template class TA { template friend void f2(TA&); // ... };
Zde není potřeba informativní deklarace šablony funkce f2 před definicí šablony třídy TA. AR 2013/2014
Jazyk C++ I
51
Přátelé template void f3(TA& A, U u) { A.x += static_cast(u); }
Šablona funkce f3 je přítelem šablony třídy TA, mající dva typové parametry T a U. Parametr T je identický s formální parametrem T šablony třídy TA. Mohl by mít i jiné označení. AR 2013/2014
Jazyk C++ I
52
Přátelé template class TB { T y; public: TB(T _y) : y(_y) {} template void g(TA& A) { y += A.x; } };
Přítelem šablony třídy TA je také specializace šablony třídy TB pro typ long. Metodu g lze tedy volat pouze pro instanci typu TB.
TB B1(3); TB B2(3.5); B1.g(A); // OK B2.g(A); // Error
AR 2013/2014
Jazyk C++ I
53
Přátelé Přítelem šablony třídy TA je také libovolná instance šablony třídy TC. template class TC { T z; public: TC(T _z) : z(_z) {} template void h(TA& A) { z += A.x; } }; Metodu h lze tedy volat pouze pro libovolnou instanci TC. TC<double> C(3.2); C.h(A); // OK
AR 2013/2014
Jazyk C++ I
54
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