Přehled šablon
Šablony, které jsou někdy označovány jako parametrizované typy, jsou mechanismy pro generování funkcí a tříd na základě typů parametrů.Pomocí šablon lze navrhnout jedinou třídu nebo funkci, která pracuje s daty mnoha typů, aniž by bylo třeba vytvořit pro každý typ samostatné třídy.
Poznámky
Například k vytvoření typově bezpečné funkce, která vrací minimálně dva parametry bez použití šablony, by bylo třeba napsat přetížené funkce takto:
// what_are_templates1.cpp
// compile with: /c
// min for ints
int min( int a, int b ) {
return ( a < b ) ? a : b;
}
// min for longs
long min( long a, long b ) {
return ( a < b ) ? a : b;
}
// min for chars
char min( char a, char b ) {
return ( a < b ) ? a : b;
}
Pomocí šablon lze snížit tyto duplikace na jedinou šablonu funkce:
// what_are_templates2.cpp
// compile with: /c
template <class T> T min( T a, T b ) {
return ( a < b ) ? a : b;
}
Šablony mohou výrazně snížit velikost zdrojového kódu a zvýšit flexibilitu kódu, aniž by byla snížena typová bezpečnost.
Existují dva hlavní typy šablon: šablony funkcí a šablony tříd.V předchozím příkladu představuje min šablonu funkce.Šablona třídy je třída s parametrem, jako například:
// what_are_templates3.cpp
template <class T> class A {
T m_t;
public:
A(T t): m_t(t) {}
void f(T t);
};
int main() {
A<int> a(10);
}
Šablony jsou deklarovány a definovány tak trochu jako další funkce a třídy s některými významnými rozdíly.Deklarace šablony plně nedefinuje funkci nebo třídu. Definuje pouze syntaktickou kostru třídy nebo funkce.Daná třída nebo funkce je vytvořena pomocí šablony procesem nazývaným vytvoření instance.Na jednotlivé vytvořené třídy nebo funkce je odkazováno jako na instancované.Například šablona třídy:
template <class T> struct A { . . . };
slouží k vytvoření instancí třídy pro A<int>, A<char>, A<int*>, A<MyClass*> a tak dále.
Vytvoření instance tříd nebo funkcí lze provést explicitně nebo implicitně.Explicitní vytvoření instance představuje způsob volání v kódu, kde se určí, které verze šablony se mají generovat.Implicitní vytváření instance umožňuje šablonám vytvářet instance podle potřeby, na základě místa, kde jsou poprvé použity.
Šablony mohou také být parametrizovány parametrem hodnoty, v jehož případě je deklarován parametr šablony jako parametr funkce.Typy s plovoucí řádovou čárkou a typy tříd nejsou povoleny jako hodnoty parametru.
// what_are_templates4.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;
template <int i> class A {
int array[i];
public:
A() { memset(array, 0, i*sizeof(int)); }
};
int main() {
A<10> a;
}
Běžný problém u šablon je, že mohou poskytovat one-size-fits-all řešení, což znamená, že stejný kód platí pro všechny typy.Pokud bude zapotřebí upravit chování šablony pro určitý typ, je možné použít specializaci.Použitím explicitní specializace lze šablonu specializovat pro konkrétní reálný typ obecného typu.Šablona typu může být také částečně specializovaná, což je užitečné, pokud existuje šablona s více typy parametrů a je zapotřebí přizpůsobit chování s ohledem na některé, ale ne všechny parametry.Částečná specializace je stále generická a pro vytvoření reálně instancované třídy vyžaduje reálné argumenty šablony.