Шаблоны (templates) — механизм метапрограммирования, позволяющий создавать обобщённые алгоритмы и структуры данных. Они обеспечивают статический полиморфизм и выполняются на этапе компиляции.
template<typename T>
T max(T a, T b) {
return a > b ? a : b;
}
Пример инстанцирования:
int m1 = max(3, 5); // Инстанцируется max<int>
double m2 = max(2.5, 3.14); // Инстанцируется max<double>
template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
return t + u;
}
template<typename T, size_t N>
class Array {
T data[N];
public:
T& operator[](size_t idx) { return data[idx]; }
};
template<typename T>
constexpr T pi = T(3.1415926535897932385);
Пример:
template<typename T>
void foo(T t) {
bar(); // Фаза 1 - должна существовать всегда
t.baz(); // Фаза 2 - проверяется при инстанцировании
}
template<>
const char* max(const char* a, const char* b) {
return strcmp(a, b) > 0 ? a : b;
}
template<typename T>
class Vector<T*> { // Специализация для указателей
// ...
};
Принцип, при котором ошибочные подстановки не вызывают ошибку компиляции, а просто исключают шаблон из перегрузки:
template<typename T>
auto test(T t) -> decltype(t.serialize(), void()) {
// Работает только для типов с методом serialize()
}
template<typename T>
concept Serializable = requires(T t) {
{ t.serialize() } -> std::convertible_to<std::string>;
};
template<Serializable T>
void save(T obj) {
// ...
}
auto generic_lambda = []<typename T>(T param) {
// ...
};
template class vector<int>; // Явное инстанцирование
Метафункция для проверки типа:
template<typename T>
struct is_pointer {
static constexpr bool value = false;
};
template<typename T>
struct is_pointer<T*> {
static constexpr bool value = true;
};
// Использование:
bool ip = is_pointer<int*>::value; // true
Резюмируем: шаблоны C++ — мощный инструмент абстракции, работающий на этапе компиляции. Их механизм основан на инстанцировании конкретных версий для каждого набора параметров, что обеспечивает гибкость без потери производительности в runtime.