C++: Szablony I

Składnia szablonu

Definicja szablonu funkcji bądź klasy wygląda tak jak zwykła definicja funkcji czy klasy, ale można w niej też używać

Definicja szablonu funkcji bądź klasy jest definicją odroczoną, a więc sama w sobie nie powoduje wygenerowania żadnego kodu.

Konkretyzacja szablonu

  • Tworząc funkcję bądź klasę na podstawie szablonu, w miejsce parametru typu można wstawić dowolny typ wbudowany bądź stworzony przez użytkownika.
  • Wszystkie wywołania funkcji i operatorów na rzecz obiektów tego typu muszą mieć sens, to znaczy stosowne operatory i funkcje muszą być zdefiniowane
  • Jeśli jakiejś definicji dla danego typu brakuje, w momencie konkretyzacji sygnalizowany jest błąd.

Na przykład, jeśli chcemy wykorzystać szablon funkcji

template<typename T>
T max(T a,T b){
  return a>b ? a : b;
}
dla argumentów z klasy samochod, to kompilator zgłosi błąd, jeśli do definicji tej klasy nie dodamy metody operator>.


Konkretyzacja szablonu funkcji

C++11: Szablony zewnętrzne (extern templates)

  template class MyClass<double>;
  extern template class MyClass<double>;

Jawne określenie typu w konkretyzacji szablonu funkcji

Natomiast próba wywołania

   max(3,3.14);
spowoduje błąd, bo nie da się wygenerować funkcji o nagłówku max(int,float) ani max(int,double) z szablonu o na główku
  template<typename T>
  inline T const& max(T const& a, T const& b);

Konwersje standardowe funkcjonują dopiero po wygenerowaniu funkcji z szablonu, a nie przed.

Deklaracja szablonu

Szablony, a typy wbudowane

Dla zachowania jednorodności funkcji szablonowych w odniesieniu tak do typów wbudowanych jak i zdefiniowanych przez użytkownika przyjęto następujące rozszerzenia języka w odniesieniu do typów wbudowanych

Szablon klasy pojemnik i konstruktor domniemany dla typów wbudowanych

Szablony z kilku parametrami

Wykorzystywanie parametrów szablonu

Przykład użycia parametru w ciele funkcji szablonowej

Parametr na typ rezultatu funkcji

Przykład szablonu z parametrem na typ rezultatu funkcji

Typy pochodne od parametru szablonu

Mając dany parametr szablonu T, w definicji szablonu możemy swobodnie tworzyć typy pochodne od typu T, na przykład tablicę T[5], czy też wskaźnik T*

Pozatypowe parametry szablonu

Parametr będący wyrażeniem typu całkowitoliczbowego

Użycie parametru typu całkowitoliczbowego pozwala na przykład zrealizować stos w wersjach z różną pojemnością.

template<typename T,int CAPACITY>
class Stack{
  T Stack[CAPACITY];
  int top;
public:
  ...
  void push(T const& t);
  T pop();
};

Teraz możemy utworzyć różne stosy;

Stack<int,10> s1;
Stack<double,5> s2;
Stack<interval,15> s3;

Przykład z szablonem klasy Stack

Parametr będący wskaźnikiem

Natomiast można napisać

char const c[]="Hej!";
jakasKlasa<c> x;

Przykład z parametrem będącym wskaźnikiem

Pozatypowe parametry szablonu funkcji

Przykład z pozatypowymi parametrami szablonu funkcji

Szablony parametrów szablonów

Przykład z szablonem parametru szablonu