← Назад к вопросам
Что такое шаблоны (templates)? Чем отличаются от дженериков в других языках?
2.0 Middle🔥 111 комментариев
#ООП и проектирование#Структуры данных и алгоритмы#Язык C++
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Шаблоны (Templates) в C++
Шаблоны позволяют писать обобщённый код, работающий с разными типами. Это compile-time полиморфизм.
Шаблоны функций
template<typename T>
T max(T a, T b) {
return a > b ? a : b;
}
int main() {
std::cout << max(5, 3) << std::endl; // 5
std::cout << max(3.14, 2.71) << std::endl; // 3.14
return 0;
}
Компилятор генерирует функцию для каждого типа: max<int>, max<double>.
Шаблоны классов
template<typename T>
class Container {
private:
T data;
public:
Container(T val) : data(val) {}
T get() const { return data; }
};
int main() {
Container<int> intC(42);
Container<std::string> strC("hello");
return 0;
}
Нетиповые параметры
template<int SIZE>
class Array {
private:
int data[SIZE];
public:
int getSize() const { return SIZE; }
};
int main() {
Array<10> arr;
return 0;
}
Специализация шаблонов
// Частичная специализация для указателей
template<typename T>
class Container {
public:
void describe() { std::cout << "Generic" << std::endl; }
};
template<typename T>
class Container<T*> {
public:
void describe() { std::cout << "Pointer" << std::endl; }
};
Шаблоны vs Дженерики
C++ Templates:
- Инстанциируются на этапе компиляции
- Полная информация о типе при компиляции
- Есть частичная специализация
- Возможно метапрограммирование
- Code bloat — каждый тип = отдельный код
Java Generics (и другие):
- Type erasure — информация о типе теряется после компиляции
- List<Integer> и List<String> становятся одним List
- Нет частичной специализации
- Быстрее компилировать
- Менее гибко
Концепты (C++20)
#include <concepts>
template<typename T>
concept Addable = requires(T a, T b) {
{ a + b } -> std::convertible_to<T>;
};
template<Addable T>
T add(T a, T b) {
return a + b;
}
Практический пример
template<typename T>
class Stack {
private:
std::vector<T> items;
public:
void push(T value) { items.push_back(value); }
T pop() {
T top = items.back();
items.pop_back();
return top;
}
bool isEmpty() const { return items.empty(); }
};
int main() {
Stack<int> intStack;
intStack.push(1);
intStack.push(2);
std::cout << intStack.pop() << std::endl; // 2
return 0;
}
SFINAE (Substitution Failure Is Not An Error)
#include <type_traits>
template<typename T>
enable_if<std::is_integral<T>::value>::type
process(T value) {
std::cout << "Integer" << std::endl;
}
template<typename T>
enable_if<std::is_floating_point<T>::value>::type
process(T value) {
std::cout << "Float" << std::endl;
}
Резюме
Шаблоны в C++:
- Compile-time полиморфизм через инстанциирование кода
- Работают с любыми типами — функции, классы
- Более гибкие чем дженерики в Java/C#
- Поддерживают специализацию и метапрограммирование
- Отличаются от дженериков: нет type erasure
- C++20 добавил концепты для ограничения типов