Czasami dla konkretnego typu operacje, które wykonuje szablon muszą być inne. Gdybyś chciał np. zrobić funkcję, która dodaje wszystkie możliwe typy wbudowane do siebie i robi to zgodnie z ich znaczeniem, to nie ma problemu dla typów int, czy float. Jednak charów (powiedzmy, że ich znaczeniem są literki) nie da się dodawać a typ bool powinieneś dodawać zgodnie z regułami algebry Boole'a. Dlatego dla tych dwóch typów powinieneś specjalizować szablon, bo to (dodawanie) robi się inaczej niż dla pozostałych. Mało szczęśliwy ten przykład, bo jest abstrakcyjny a nie konkretny. ;-)
Znalazłem konkretniejszy przykład - funkcję, która konwertuje wszystko do stringów, uzywając std::stringstream i operatora << (zadziała dla każdej klasy, dla której przeciążony jest ten operator, całkiem poręczne)
template<typename T>
std::string toString(const T &value) {
std::ostringstream stream;
if (!(stream << value)) {
// jakistam wyjatek
}
return stream.str();
}
Ale dla typu bool trzeba zrobić to inaczej, bo chcemy, żeby ładnie wyglądało:
template<>
std::string toString<bool>(const bool &value) {
if (value) {
return std::string("true");
} else {
return std::string("false");
}
}