Chciałbym zwrócić Waszą uwagę na ciekawostkę w C++ związaną z szablonami. Najpierw pewien przykład:
Oto prosty program liczący silnię z dowolnej liczby. Załóżmy że mamy jakieś znane już podczas kompilacji dane, np. liczbę 10, dla której chcemy znać silnię.
#include <iostream.h>
int SilniaN(int X)
{
if(X==0) return 1;
if(X==1) return 1;
return X * SilniaN(X-1);
}
void main()
{
cout<<SilniaN(10);
}
Wynikiem będzie oczywiście silnia z 10 czyli 3628800
Teraz przedstawię inny sposób rozwiązania tego zadania:
#include <iostream.h>
template <int N>
struct SilniaT
{
enum{ X = N * SilniaT<N-1>::X };
};
template <> struct SilniaT<0> { enum{ X = 1}; };
template <> struct SilniaT<1> { enum{ X = 1}; };
#define SilniaS( A ) SilniaT< A >::X
void main()
{
cout<<SilniaS(10);
}
Wynik jest również 3628800. Więc po co tak komplikować?
Chodzi o szybkość wykonywania tych programów. Zmierzyłem czas dla 50000000 wykonanych operacji w trybie normalnym czyli dla funkcji SilniaN. Wynosił on na mojej maszynie ok. 16 sekund. Potem zmierzyłem czas dla takiej samej ilości operacji dla funkcji SilniaS. Czas wykonania wyniosł 0 sekund [!!!]
Jak to możliwe?
Otóż wszystkie obliczenia wykonały się zanim program został uruchomiony, jeszcze w kompilatorze. W rzeczywistości program ma na stałe wpisane gotowe wartości. Wydłużył się jedynie nieznacznie czas kompilacji.
- To wspaniale! - powiesz - Teraz mogę pisać programy, które wymiatają swoją szybkością, bo wszystkie obliczenia wykona kompilator!
Pamiętaj jednak, że DANE MUSZĄ BYĆ ZNANE JUŻ PRZY KOMPILACJI.
Prawdą jest, że ten sposób i tak jest bardzo pomocny, bo podczas kompilacji zawsze jakieś dane są już znane. Wtedy możemy wykorzystywać właśnie rozwiązanie szablonowe. Do tego jak to robić napisano nawet osobne książki.
Udowodniono nawet, że każdy algorytm można wpisać w szablon. Pisanie jednak takich dziwolongów nie jest już sprawą prostą więc pozostaje to (przynajmniej dla mnie) na razie tylko ciekawostką.