Где можно писать шаблоны (templates) в C++?

«Где можно писать шаблоны (templates) в C++?» — вопрос из категории Шаблоны, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Шаблоны в C++ можно писать в различных местах, но основное правило связано с моделью компиляции: компилятору нужен полный код шаблона в момент его инстанцирования (создания конкретной версии для типа).

Основные места размещения:

  1. Заголовочные файлы (.hpp/.h): Наиболее распространенный и удобный способ. Весь код шаблона (объявление и определение) находится в заголовке.

    // vector_utils.hpp
    #pragma once
    
    template <typename T>
    class SimpleVector {
    private:
        T* data_;
        size_t size_;
    public:
        explicit SimpleVector(size_t size) : size_(size), data_(new T[size]) {}
        ~SimpleVector() { delete[] data_; }
        T& operator[](size_t index) { return data_[index]; }
    };
    
    template <typename T>
    T sum(const SimpleVector<T>& vec) { /* реализация здесь */ }
  2. Явное инстанцирование в .cpp файле: Можно вынести определение шаблона в .cpp файл, но тогда необходимо явно инстанцировать его для всех используемых типов. Это сокращает время компиляции.

    // my_template.cpp
    template <typename T>
    T max(T a, T b) { return (a > b) ? a : b; }
    
    // Явное инстанцирование для int и double
    template int max<int>(int, int);
    template double max<double>(double, double);

    В заголовке останется только объявление: template <typename T> T max(T a, T b);.

  3. Внутри классов/структур: Шаблонные методы можно определять прямо внутри класса.

    template <typename Key, typename Value>
    class Cache {
    public:
        // Шаблонный метод внутри шаблонного класса
        template <typename InputIt>
        void insertRange(InputIt first, InputIt last) {
            for (; first != last; ++first) {
                storage_.insert(*first);
            }
        }
    private:
        std::map<Key, Value> storage_;
    };

Рекомендация: Для большинства проектов полное определение шаблонов в заголовочных файлах — это стандартный и наименее проблемный подход.