C++ Templates
V C++ sú šablóny (templates) mechanizmus generického programovania, ktorý umožňuje písať funkcie alebo triedy parametrizované typom (alebo aj inými hodnotami). Kompilátor pri použití šablóny automaticky „vygeneruje“ konkrétnu verziu pre každý skutočný typ, ktorý sa pri vyvolaní použije.
1. Základná definícia funkčnej šablóny
template<typename Tp> // alebo template<class Tp>
void print_vector(vector<Tp> &v) {
for (auto i : v)
cout << i << " ";
cout << endl;
}
template<typename Tp>
hovorí kompilátoru:„Nasledujúca funkcia bude parametrizovaná jedným typovým parametrom
Tp
.”V tele funkcie potom namiesto konkrétneho
int
,double
či nejakého iného typu používameTp
.
2. Ako kompilátor generuje kód (instantiácia)
Keď v main()
napíšete:
vector<int> vi = {1,2,3};
vector<string> vs = {"a","b","c"};
print_vector(vi); // Tp := int
print_vector(vs); // Tp := std::string
- Kompilátor v momente prvého volania
print_vector(vi)
vytvorí verziuprint_vector<int>(vector<int>&)
. - Pri
print_vector(vs)
zasa vznikneprint_vector<std::string>(vector<std::string>&)
. - Vznikajú teda dve samostatné funkcie – ani jedna nevyžaduje runtime „kontrolu typu”, všetko sa rieši počas prekladu.
3. Výhody funkčných šablón
- Žiadne duplicitné písanie kódu
Nemusíte robiť overloady prevector<int>
,vector<double>
,vector<char>
atď. – jedna šablóna pokryje všetky. - Typová bezpečnosť
Ak sa pokúsite zavolaťprint_vector(42)
, kompilátor vyhodí chybu, pretože neexistujevector<Tp>
pre jedenint
. - Výkon
Vygenerovaný kód je špecializovaný a optimalizovaný pre konkrétny typ, bez dynamic dispatch či virtuálnych volaní.
4. Použitie viacerých parametrov
Okrem jedného typu môžete mať niekoľko:
template<typename Key, typename Value>
pair<Key, Value> make_pair(const Key& k, const Value& v) {
return {k, v};
}
make_pair<int, string>(42, "abc")
vygeneruje pár(int, string)
.
5. Non-type šablónové parametre
Šablóna môže mať aj hodnotový parameter:
template<typename T, size_t N>
void print_array(const T (&arr)[N]) {
for (size_t i = 0; i < N; i++)
cout << arr[i] << " ";
cout << endl;
}
- Tu
N
je konštanta (napr. veľkosť poľa) známa pri kompilácii.
6. Špecializácie
Ak potrebujete pre konkrétny typ zmeniť správanie, definujete špecializáciu:
template<>
void print_vector<bool>(vector<bool> &v) {
// špeciálna implementácia pre bool (ktoré v STL absence priamych bool&)
}
- Prázdny
<…>
zatemplate
a typ vo zátvorke hovoria, že ide o špeciálny prípad.
Zhrnutie
- Šablóna sa definuje kľúčovým slovom
template<…>
. - Typový parameter (
typename
aleboclass
) umožňuje písať generický kód. - Kompilátor pri použití (instantiácii) vytvorí konkrétne verzie funkcie/triedy.
- Použitie šablón zvyšuje znovupoužiteľnosť a typovú bezpečnosť bez straty výkonu.