Инстанциация шаблона — это процесс генерации конкретного кода (класса или функции) на основе шаблона при подстановке конкретных типов или значений вместо параметров шаблона.
Когда компилятор встречает использование шаблона с конкретными параметрами:
template <typename T>
T max(T a, T b) {
return a > b ? a : b;
}
// Инстанциации:
int m1 = max<int>(5, 10); // Генерируется int max(int, int)
double m2 = max<double>(3.14, 2.7); // Генерируется double max(double, double)
Программист явно указывает, какие версии шаблона нужно сгенерировать.
// Явное инстанцирование шаблона функции
template int max<int>(int, int);
// Явное инстанцирование шаблона класса
template class std::vector<std::string>;
Компилятор автоматически генерирует нужные версии при использовании.
std::vector<int> v; // Неявное инстанцирование vector<int>
max(5, 10); // Неявное инстанцирование max<int>
Генерация шаблона для частично указанных параметров.
template <typename T1, typename T2>
class Pair { /*...*/ };
// Частичная специализация
template <typename T>
class Pair<T, int> { /*...*/ };
Фаза определения:
Фаза инстанциации:
template <typename T>
void foo(T x) {
unrelated(); // Проверяется в фазе определения
x.method(); // Проверяется в фазе инстанциации
}
Можно явно указать точку инстанциации:
template void std::swap<int>(int&, int&); // Явная точка инстанциации
ODR (One Definition Rule):
Ленивая инстанциация:
template <typename T>
class Wrapper {
T value; // Инстанцируется только при полном определении T
public:
void set(const T& v) { value = v; } // Инстанцируется при вызове
};
Взрыв кода (code bloat):
Длинное время компиляции:
Ошибки в шаблонах:
template <typename T, size_t N>
class Array {
T data[N];
public:
template <typename U>
Array(const U (&arr)[N]) { // Шаблонный конструктор
for(size_t i = 0; i < N; ++i)
data[i] = arr[i];
}
};
int main() {
double source[3] = {1.1, 2.2, 3.3};
Array<int, 3> arr(source); // Инстанцируется:
// 1. Array<int, 3>
// 2. Конструктор Array<int,3>::Array<double>(const double (&)[3])
}
Резюмируем: инстанциация шаблонов — ключевой механизм C++, позволяющий генерировать эффективный типобезопасный код на этапе компиляции. Понимание этого процесса критически важно для эффективного использования шаблонов и диагностики связанных с ними ошибок.