ПрограммированиеC++ разработчик

Что такое шаблоны (templates) в C++? Какие типы шаблонов существуют? Какие трудности и ошибки возникают при проектировании и использовании шаблонов? Покажите пример шаблона класса и функции.

Проходите собеседования с ИИ помощником Hintsage

Ответ.

Шаблоны (templates) — механизм C++, позволяющий создавать обобщённые классы и функции, работоспособные с различными типами данных без дублирования кода. Это основа реализации контейнеров STL, алгоритмов и многих паттернов обобщённого программирования.

Типы шаблонов:

  • Шаблоны функций: позволяют создавать одну функцию для разных типов.
  • Шаблоны классов: позволяют создавать классы, работающие с разными типами.
  • Шаблоны с параметрами-значениями: можно параметризовать не только типами, но и константными значениями.

Пример шаблона класса:

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

Пример шаблона функции:

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

Вопрос с подвохом.

Можно ли явным образом специализировать только один метод шаблонного класса, не специализируя весь класс? Если да, как это делается?

Ответ:
Да, можно. Необязательно специализировать весь класс; можно просто специализировать отдельный метод:

template <typename T> class Foo { public: void bar(); }; template <> void Foo<int>::bar() { // Специализация только метода bar для int // Реализация }

Примеры реальных ошибок из-за незнания тонкостей темы.


История
В проекте был написан шаблон функции для сравнения:

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

При использовании с типами, не имеющими оператора <, возникла ошибка компиляции, которую долго искали, т.к. диагностика выдавалась только при инстанцировании шаблона, а не в месте его определения.


История
Разработчик пытался использовать в шаблонной функции сложение для пользовательского класса, забыв перегрузить оператор +. Это привело к ошибкам компиляции при первом же вызове с этим классом.


История
При разработке контейнера на основе шаблона класса был сделан метод, который не зависел от типа шаблона, но был вынесен за пределы класса без явной специализации:

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

Это привело к ошибке компоновки, потому что специализация объявилась, но не была реализована корректно для всех типов.