programowanieProgramista C++

Czym są szablony (templates) w C++? Jakie typy szablonów istnieją? Jakie trudności i błędy występują przy projektowaniu i używaniu szablonów? Pokaż przykład szablonu klasy i funkcji.

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

Szablony (templates) — mechanizm C++, który pozwala na tworzenie ogólnych klas i funkcji, działających z różnymi typami danych bez powielania kodu. To podstawa realizacji kontenerów STL, algorytmów i wielu wzorców programowania ogólnego.

Typy szablonów:

  • Szablony funkcji: pozwalają na stworzenie jednej funkcji dla różnych typów.
  • Szablony klas: pozwalają na tworzenie klas działających z różnymi typami.
  • Szablony z parametrami-wartościami: można parametryzować nie tylko typy, ale i stałe wartości.

Przykład szablonu klasy:

template<typename T> class Box { public: Box(T value): data(value) {} T get() const { return data; } private: T data; };

Przykład szablonu funkcji:

template<class T> T add(const T& a, const T& b) { return a + b; }

Pytanie z haczykiem.

Czy można jawnie specjalizować tylko jedną metodę szablonowej klasy, nie specjalizując całej klasy? Jeśli tak, to jak to zrobić?

Odpowiedź:
Tak, można. Nie trzeba specjalizować całej klasy; można po prostu specjalizować pojedynczą metodę:

template <typename T> class Foo { public: void bar(); }; template <> void Foo<int>::bar() { // Specjalizacja tylko metody bar dla int // Implementacja }

Przykłady rzeczywistych błędów z powodu nieznania szczegółów tematu.


Historia
W projekcie została napisana szablon funkcji do porównania:

template <typename T> bool cmp(const T& a, const T& b) { return a < b; }

Przy użyciu z typami, które nie mają operatora <, wystąpił błąd kompilacji, którego długo szukano, ponieważ diagnostyka wydawana była tylko przy instancjonowaniu szablonu, a nie w miejscu jego definicji.


Historia
Programista próbował użyć w szablonowej funkcji dodawania dla klasy użytkownika, zapominając przeładować operator +. To doprowadziło do błędów kompilacji przy pierwszym wywołaniu z tą klasą.


Historia
Przy opracowywaniu kontenera opartego na szablonie klasy zrobiono metodę, która nie zależała od typu szablonu, ale została wyjęta poza klasę bez jawnej specjalizacji:

template<> int MyContainer<int>::size() const { ... }

To doprowadziło do błędu linkowania, ponieważ specjalizacja została ogłoszona, ale nie została prawidłowo zrealizowana dla wszystkich typów.