Заметки по языку с и с++

Шаблоны в C++: основы и примеры

обновлено 493 просмотров

Что такое шаблон

Шаблон (template) — это механизм языка C++, позволяющий писать обобщённый код, который работает с разными типами данных без дублирования. Компилятор сам подставляет нужный тип в момент вызова, создавая конкретную версию функции или класса.

Синтаксис объявления

Шаблон начинается с ключевого слова template. После ключевого слова идут угловые скобки < >, в которых перечисляется список параметров шаблона.

Например:

template <typename T>

Ключевое слово typename сообщает, что будет использован встроенный тип данных. К таким типам относятся: intdoublefloatchar и другие.

Примечание: в объявлении ключевое слово пишется строчными буквами — template, а не Template. C++ чувствителен к регистру, поэтому Template вызовет ошибку компиляции.

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

Рассмотрим фрагмент кода с использованием шаблона:

template <typename T>
T test(const T a, const T b)
{
    return a + b;
}

Здесь T — параметр шаблона, который при вызове заменяется на конкретный тип. Функция test() принимает два аргумента одного типа и возвращает их сумму.

Вызов функции шаблона

double a = test(1.2, 2.3);
int b = test(1, 2);
float c = test(1.0, 2.3);

Компилятор автоматически выводит тип T из переданных аргументов:

  • test(1.2, 2.3) → T = double, результат 3.5;
  • test(1, 2) → T = int, результат 3;
  • test(1.0, 2.3) → T = double, результат 3.3 (результат затем приводится к float при присваивании c).

Явное указание типа

При необходимости тип можно задать явно:

double a = test<double>(1, 2);   // T = double, результат 3.0
int b = test<int>(1.2, 2.3);     // T = int, аргументы приводятся к 1 и 2, результат 3

Это полезно, когда автоматический вывод даёт не тот тип, который нужен.

Важные замечания

  1. typename и class в параметрах шаблона эквивалентны. Оба обозначают тип:cpptemplate <typename T> // эквивалентно template <class T>Слово typename появилось позже и считается более корректным для типов-параметров.
  2. Шаблоны не компилируются сами по себе. Конкретный код генерируется в момент инстанцирования (подстановки типа). Поэтому ошибки в теле шаблона проявляются только при вызове с конкретным типом.
  3. Определение шаблона должно быть видно в точке вызова. Обычно шаблоны размещают в заголовочных файлах (.h), а не в .cpp — иначе компоновщик не найдёт нужную инстанциацию.
  4. Параметров шаблона может быть несколько:cpptemplate <typename T, typename U> auto sum(T a, U b) -> decltype(a + b) { return a + b; }
  5. Шаблоны работают не только с встроенными типами. Параметром может быть любой тип — QString, пользовательский класс и т. д. Главное, чтобы для него были определены используемые операции (например, operator+).
  6. Ограничения (C++20). В современном C++ можно явно задать требования к типу через концепты:cpptemplate <std::integral T> T test(T a, T b) { return a + b; }
  7. Шаблоны классов. Помимо функций, шаблоны применимы и к классам:cpptemplate <typename T> class Box { T value; public: void set(const T &v) { value = v; } T get() const { return value; } };

Итог

Шаблоны — мощный инструмент C++ для написания обобщённого кода, работающего с разными типами без дублирования. Ключевое слово template вместе с параметрами в угловых скобках задаёт «заготовку», а компилятор при вызове сам подставляет нужный тип. Основные правила: пишите template строчными буквами, размещайте определения в заголовках и помните, что конкретный код генерируется только в момент вызова.