Kako napisati jednu funkciju koja radi i sa int, i sa double, i sa string? Pomoću šablona: tip postaje parametar, a prevodilac sam pravi verziju za svaki tip koji se koristi. Na ovaj način su napravljeni vector, sort i ceo STL.
Pre nego što počneš: potrebno predznanje – nasleđivanje, STL. Kako da učiš: svaki primer prekucaj i pokreni, a zadatke na kraju prvo reši sam/a; uputstvo i rešenje otvori tek posle toga. Svi programi su u C++-u (C++17) i provereno se prevode i daju navedeni izlaz.
Šablonska funkcija
#include <bits/stdc++.h>
using namespace std;
template <typename T> // T je "bilo koji tip"
T najveci(const vector<T>& v) {
T m = v[0];
for (const T& x : v)
if (m < x) m = x; // T mora da podržava operator <
return m;
}
template <typename T>
void ispisi(const vector<T>& v) {
for (size_t i = 0; i < v.size(); i++)
cout << v[i] << (i + 1 < v.size() ? ", " : "\n");
}
int main() {
vector<int> brojevi = {4, 9, 2};
vector<double> visine = {1.62, 1.75, 1.58};
vector<string> imena = {"Mila", "Ana", "Teodora"};
cout << najveci(brojevi) << " " << najveci(visine) << " " << najveci(imena) << "\n";
ispisi(imena);
return 0;
}
Prevodilac na osnovu argumenta sam zaključi T (int, double, string) i napravi tri verzije funkcije. Najveći string je „Teodora“, jer se stringovi porede abecedno (T dolazi posle M i A).
Pri korišćenju šablonske klase tip se navodi u uglastim zagradama: Stek<char>, Stek<int> – kao vector<int>. Stek je detaljno objašnjen u lekciji Stek.
Više parametara i auto
#include <bits/stdc++.h>
using namespace std;
template <typename K, typename V>
V vrednostIliPodrazumevano(const map<K, V>& m, const K& kljuc, const V& podrazumevano) {
auto it = m.find(kljuc);
return it == m.end() ? podrazumevano : it->second;
}
int main() {
map<string, int> bodovi = {{"Ana", 95}, {"Iva", 80}};
cout << vrednostIliPodrazumevano(bodovi, string("Ana"), 0) << " "
<< vrednostIliPodrazumevano(bodovi, string("Luka"), 0) << "\n";
auto zbir = [](auto a, auto b) { return a + b; }; // "šablonska" lambda (C++14)
cout << zbir(2, 3) << " " << zbir(1.5, 2.25) << " " << zbir(string("ab"), string("cd")) << "\n";
return 0;
}
Zapis
Značenje
template <typename T>
šablon sa jednim tipom (može i class T – isto je)
template <typename K, typename V>
više tipova
template <typename T, int N>
i broj može biti parametar (npr. array<int, 5>)
auto u lambdi
kraći način za jednostavne šablonske funkcije
Zadaci za vežbu
Za svaki zadatak postoji primer, uputstvo i rešenje. Rešenja su provereno tačna na primerima iz teksta.
ZADATAK 01Težina: lako
Brojanje većih od proseka
Napiši šablonsku funkciju vecihOdProseka(const vector<T>& v) koja vraća koliko elemenata je strogo veće od proseka. Učitati n celih brojeva, pa m realnih i ispisati oba rezultata.
Primer
Ulaz
5
1 2 3 4 5
3
1.5 2.5 10.0
Izlaz
2 1
Uputstvo
Prosek računaj kao double: zbir u double pa podeli sa v.size().
Rešenje (C++)
#include <bits/stdc++.h>
using namespace std;
template <typename T>
int vecihOdProseka(const vector<T>& v) {
double zbir = 0;
for (const T& x : v) zbir += x;
double prosek = zbir / v.size();
int k = 0;
for (const T& x : v)
if (x > prosek) k++;
return k;
}
int main() {
int n, m;
cin >> n;
vector<int> a(n);
for (int& x : a) cin >> x;
cin >> m;
vector<double> b(m);
for (double& x : b) cin >> x;
cout << vecihOdProseka(a) << " " << vecihOdProseka(b) << "\n";
return 0;
}
Česte greške i saveti
Šablon se piše ceo u zaglavlju (.h) ili istom fajlu – prevodilac mora da vidi kod da bi napravio verziju za novi tip.
Greške u šablonima su duge i nečitke; traži prvi red koji pominje tvoj fajl i red.
Tip mora da podržava sve operacije iz šablona (npr. < za najveci) – inače greška pri prevođenju.
Proveri znanje
Otvori kviz
Šabloni
1. Šta je T u template <typename T>?
2. Kako se pravi objekat šablonske klase Stek za cele brojeve?
3. Koji deo STL-a NIJE šablon?
Podešavanja kolačića
Koristimo kolačiće da bismo vam pružili najbolje moguće iskustvo. Takođe nam omogućavaju da analiziramo ponašanje korisnika kako bismo stalno poboljšavali veb lokaciju za vas.