Wikipedysta:Matekm/Szablony języka C++/Szablony języka C++/Podstawy

Z Wikibooks, biblioteki wolnych podręczników.

Szablony funkcji[edytuj]

Zdarza się czasami, że programista staje przed zadaniem funkcji, która będzie wykorzystywana z różnego rodzaju typami danych. Przykładowo, na potrzebę tej książki, niech to będzie funkcja zwracająca minimum z dwóch podanych wartości. Dla typów całkowitoliczbowych definicja tej funkcji może wyglądać następująco:

int min(int p1, int p2)
{
    return (p1 < p2) ? p1 : p2;
}

W różnych projektach często się jednak zdarza, że ten sam kod mógłby być użyty w innymi typami. Wspomniany programista może, przykładowo, zauważyć, że potrzebuje także funkcji min dla typów zmiennoprzecinkowych oraz typu zdefiniowanego przez siebie. W "tradycyjnym" programowaniu w tej sytuacji zmuszony by został do napisania przeciążonej implementacji funkcji min dla zadanych typów:

float min(float p1, float p2)
{
    return (p1 < p2) ? p1 : p2;
}


MyType min(MyType p1, myType p2)
{
    return (p1 < p2) ? p1 : p2;
}

W powyższych przykładach dokładnie widać, że ciało każdej z funkcji min jest dokładnie takie samo. Jedyna różnica to sygnatury funkcji. Kod tworzony w taki sposób jest trudny w utrzymywaniu, czytaniu, używaniu a dodatkowo podatny jest na trudne do wykrycia błędy.

Problem tak zduplikowanego kodu może zostać rozwiązany przez szablony języka C++ - potężny mechanizm ułatwiający wykorzystywanie już istniejącego kodu z różnymi typami.

Najprostszym rodzajem szablonów stosowanych w języku C++ są szablony funkcji, umożliwiające zdefiniowanie rodziny funkcji, których wykonanie będzie możliwe dla różnych typów danych, zarówno tych wbudowanych jak int, double czy char, jak i typów zdefiniowanych przez użytkownika. Szablony funkcji często stosowane są zamiast przeciążania w sytuacji, gdy użytkownik musi zdefiniować funkcje zachowujące się identycznie dla różnych typów danych.

Definiowanie szablonów funkcji zasadniczo nie odbiega od definiowania klasycznych funkcji, są jednak pewne różnice. Poniżej znajduje się definicja prostego szablonu funkcji, która zwraca minimum z dwóch przekazanych wartości

template<typename T>
T min(T &p1, T &p2)
{
    return (p1 < p2) ? p1 : p2;
}

Definicję każdego szablonu funkcji rozpoczyna słowo kluczowe template, po którym należy podać parametry szablonu, umieszczone w nawiasach trójkątnych; każdy parametr szablonu poprzedzony jest słowem kluczowym typename. Parametry szablony stanowią nazwę, która używana będzie w ciele definiowanego szablonu i reprezentować będzie przekazany przez użytkownika typ.

Zdefiniowany wyżej szablon możemy w następujący sposób wykorzystać w kodzie:

T min(T &p1, T &p2)
{
    return (p1 < p2) ? p1 : p2;
}

class SampleClass
{
 public:
    SampleClass(int param) m(param) {}

    operator<(const SampleClass& p_in)
    {
        return (m < p_in.m);
    }
 private:
    int m;
};

int main()
{
    int a = 1, int b = 10;
    int m_int = min(a, b);
    assert (m_int == a);

    double c = 3.14, double d = 6.28;
    double m_double = min(c, d);
    assert (m_double == c);

    SampleClass e(10), f(100);
    SampleClass m_sample = min(e, f);
    assert (m_sample == c);

    return 0;
}