Wprowadzenie.
Jedną z ważnych funkcjonalności języka C++, które należy poznać są tak zwane szablony funkcji (Function templates). Tłumacząc w prosty sposób szablony funkcji są to funkcje specjalne z nieokreślonymi ogólnymi typami (generic types). Taka właściwość pozwala nam napisać “uniwersalną” funkcję, która przy wywołaniu może przyjmować argumenty różnych typów, bez potrzeby powtarzania całego kodu dla konkretnych typów. Opracowywanie programów w taki sposób nazywane jest programowaniem ogólnym (generic programming).
Zakres artykułu.
- Składnia szablonu funkcji
- Program w C++
- Plik Makefile
- Testy
Składnia szablonu funkcji
Składnia deklarowanego szablonu funkcji wygląda następująco:
template <class zmienna> deklaracja_funkcji;
albo
template <typename zmienna> deklaracja_funkcji;
W powyższych składniach występuje jedna różnica, którą jest słowo kluczowe class i typename. Znaczenie obu słów kluczowych jest identyczne i nie ma znaczenia w jaki sposób będziemy tworzyć szablony funkcji.
Słowo kluczowe typename jest młodsze niż class i lepiej odzwierciedla pełnioną funkcję, przez co obecnie jest bardziej zalecane.
Program w C++
Kod programu, który pozwoli na przetestowanie szablonu funkcji zapisałem w pliku main.cpp i wygląda następująco.
#include <iostream> using namespace std; template <typename T> T dodajWartosci(T a, T b) { T wynik = 0; wynik = a + b; return wynik; } int main() { int a1 = 5; int b1 = 10; int w1 = 0; float a2 = 5.1; float b2 = 10.2; float w2 = 0.0; w1 = dodajWartosci<int>(a1, b1); w2 = dodajWartosci<float>(a2, b2); cout << w1 << endl; cout << w2 << endl; return 0; }
Podczas budowania programu kompilator sprawdza jakiego typu są argumenty podstawione do szablonu funkcji, a następnie generuje on funkcje z odpowiednimi typami parametrów.
Z powyższego kodu kompilator wygeneruje następujące funkcje:
int dodajWartosci(int a, int b) { int wynik = 0; wynik = a + b; return wynik; }
oraz
float dodajWartosci(float a, float b) { float wynik = 0; wynik = a + b; return wynik; }
Powyższe dwie funkcje znajda się w kodzie wynikowym co oznacza, że długość kodu wynikowego będzie taka sama jak w przypadku gdybyśmy napisali oddzielnie funkcję dla typu int oraz float.
Plik Makefile
Plik Makefile wygląda następująco:
CC = g++
CFLAGS =
LIBS =
OBJ =\
main.o
all: main
clean:
rm -f *.o test
.c.o:
$(CC) -c $(INCLUDES) $(CFLAGS) $<
main: $(OBJ)
$(CC) $(OBJ) $(LIBS) -o test
Testy
Gdy już mamy wszystko przygotowane wówczas w konsoli wpisujemy polecenie:
$ make
Następnie uruchamiamy nasz program poleceniem:
$ ./test
Wynik jaki otrzymamy powinien wyglądać następująco:
15
15.3