1)
W przypadku przeciążania funkcji i szablonów funckji:
>algorytm rozstrzygający przeciążenie preferuje dopasowanie zwykłych funkcji nad szablonami
nie można definiować zwykłych funkcji z nazwami takimi samymi jak nazwy funckji w szablonie
>wybiera dopasowanie szablonu ?bardziej wyspecjalizowanego?, tzn. takiego do którego pasuje mniejszy zbiór argumentów
2)
Dla deklaracji szablonu w postaci:
template<typename T> T max(T a,T b) {return (a>b)?a:b;}
using namspace std;
prawidłowe są konkretyzacje:
max(7,5)
>::max(7,5)
>cout<<::max(3.1415,2.71);
>cout<<::max(7,5);
3)
struct Max
{ template<typename T> T max(T a,T b) {return (a>b)?a:b;}};
main()
{ Max m;
m.max(1,2);
m.max(1.23,2.14);
}
V >na rzecz obiektu m zostaną wywołane dwie różne metody klasy Max
nie zadziała ponieważ nie dokonano jawnej kontretyzacji szablonu metody max
nie zadziała bo dla klas nie można tworzyć szablonów metod
V >stworzy metody max dla kalsy Max dla typu int i double
4)
Szablony w C++
V >można przeciążać
nie mogą być specjalizowane - dla każdego typu tworzą funkcje o tym samym kocepcie
V >umożliwiają automatyczne generowanie kodu
implementują polimorfizm dynamiczy
5)
Czy polimorfizm dynamiczny
jest oparty o mechanizm szablonów
bezpiecznie obsługuje jednorodne zbiory obiektów
V >wymaga wspólnej hierarchii dziedziczenia
V >zazwyczaj generuje mniejszy kod
6)
template<typename T> T max(T a,T b) {return (a>b)?a:b;}
template int max<int>(int ,int) ;
V >tworzy szablon funkcji max zwracającej większy z podanych argumentów
kompilator stworzy kod funkcji max dla dowolnego typu danych
V >kompilator stworzy kod funkcji max dla typu int oraz dla każdego innego typu jeżeli wywołane zostanie na jego rzecz użycie funkcji max
kompilator stworzy kod funkcji max dla typu int
7)
template<typename T> T max(T a,T b) {return (a>b)?a:b;}
main() {
cout<<::max(3.14,2)<<endl;
cout<<::max<int>(3.14,2)<<endl;
cout<<::max<double>(3.14,2)<<endl;
}
dla drugiej konkretyzacji zgłosi błąd
dla drugiej i trzeciej konkretyzacji zgłosi błąd
dla trzeciej konkretyzacji zgłosi błąd
V >dla pierwszej konkretyzacji zgłosi błąd
8)
template<typename T> T max(T a,T b) {return (a>b)?a:b;};
w przypadku wykorzystania szablonu wymaga konstruktora kopiujacego dla typu T
V >tworzy szablon funkcji max zwracającej większy z podanych argumentów
V >wymaga konkretyzacji
>wymaga operatora > dla typu T
9)
Zakładająć uogólniony szablon klasy Stack
template<typename T> Stack
{
public:typedef T value_type;
...
}
oraz szablon funkcji
template<typename S> void f(S s)
{ typename S::value_type total;
while(!s.is_empty() )
{ total+=s.pop(); }
cout<<total;
}
>funkcja f wyświetli sume elementów stosu i go wyczyści
V >wykorzystując definicję typu stowarzyszonego otrzymujemy automatyczną konkretyzację funkcji f na dla każdego typu dla którego zdefiniujemy obiekt stosu
słowo kluczowe typename nie jest wymagane
kompilator zgłosi błąd ze względu na niemożliwość stwierdzenia jakiego typu ma być zmienna total
10)
Czy polimorfizm dynamiczny:
V >jest realizowany w opraciu o dziedzieczenie i funkcje wirtualne
nie wymusza korzystania ze wskaźników i referencji ani funkcji wirtualnych
V >wymusza korzystanie ze wskaźników lub referencji i funkcji wirtualnych
nie wymaga wspólnej hierarchii dziedziczenia
Szablony C++
Pozatypowy parametr szablonu może być
dowolnego typu
V >typ wskaźnikowego
V >typu całkowitoliczbowego bądź typu wyliczeniowego
>najczęściej jest typu całkowitoliczbowego
Szablony C++
Specjalizacja szablonu funkcji
może dotyczyć nie istniejącego szablonu ponieważ oznacza jednoczesnie definicję szablonu
nie może dotyczyć szablonów funkcji o nazwach takich samych jak funkcje zdefiniowane przez programiste poza szablonem
>w przeciwieństwie do przeciążenia, musi dotyczyć już istniejącego szablonu
>oznacza zmianę kodu już istniejącego szablonu, tak aby dla pewnego podzbioru parametrów działał inaczej
Szablony C++
Poniższa dyrektywa preprocesora
#define max(a,b) ( (a>b)?a:b) )
tworzy szablon dla funkcji max zwracjącej większy z argumentów a i b
>spowoduje zastąpienie w kodzie programu ciągu "max(a,b)" ciągiem ((a>b)?a:b))
będzie generować błedy ze względu na niepoprawny zapis
tworzy funkcję max dla dowolnego typu danych
template<typename T> class Stack
{
public: static const size_t N=100;
private: T _rep[N];
size_t _top;
public: Stack():_top(0) {};
void push(T val) {_rep[_top++]=val;}
T pop() {return _rep[--_top];}
bool is_empty {return (_top==0);}
};
nie zadziała ponieważ dla szablonu klasy nie zdefiniowano pozatypowego parametru szablonu N
>umożliwi dla każdego typu dla którego zdefiniowano konstruktor kopiujący definiowanie stosów co najwyżej 100 elementów
>stworzy szablon klasy Stack
nie zadziała ponieważ w szablonie źle zdefiniowano typ zwracany przez metode pop()
Poniższy kod
template<typename T> T max(T *data,size_t n)
{ T _max = data[0];
for(size_t i=0;i<n;i++)
if(data[i]>_max) _max=data[i];
return _max;
}
template<typename T> T max(T a,T b) {return (a>b)?a:b;};
oznacza
nic nie oznacza bo jest błdędny, nie można definiować szablonów funkcji wykonujących rózne operacje
>że dla funckji max zdefiniowano dwa szablony przeciążające jej nazwę w zależności od argumentów funckji
>w programie zostanie automatycznie stworzony kod funckji max zwracającej większy z dwóch argumentów dla typów danych dla których zostanie wywołana ta funkcja
>że kompilator automatycznie wybierze poprawną definicję na podstawie argumentów wywołania funkcji