Кратко
Инстанцирование шаблона в C++ — это процесс создания конкретной версии шаблона с заданными параметрами типа или значениями. Этот процесс происходит автоматически при использовании шаблона или может быть выполнен явно.
Автоматическое инстанцирование
Когда шаблон используется в коде, компилятор автоматически создает инстанцию шаблона для конкретного типа или значения.
#include <iostream>
template <typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
int main() {
std::cout << "Max of 3 and 7: " << max(3, 7) << std::endl; // Инстанцирование max<int>
std::cout << "Max of 3.5 and 2.1: " << max(3.5, 2.1) << std::endl; // Инстанцирование max<double>
return 0;
}
Явное инстанцирование
Можно явно указать компилятору создать инстанцию шаблона для конкретного типа или значения с помощью явного инстанцирования.
Явное инстанцирование функции
#include <iostream>
template <typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
// Явное инстанцирование шаблона функции для int
template int max<int>(int, int);
int main() {
std::cout << "Max of 3 and 7: " << max(3, 7) << std::endl;
return 0;
}
Явное инстанцирование класса
#include <iostream>
template <typename T>
class MyClass {
public:
T value;
MyClass(T val) : value(val) {}
void display() const {
std::cout << value << std::endl;
}
};
// Явное инстанцирование шаблона класса для int
template class MyClass<int>;
int main() {
MyClass<int> obj(42);
obj.display();
return 0;
}
Явная специализация
Иногда требуется создать специализированную версию шаблона для определенного типа. Это называется явной специализацией. То есть только для такой-то версии вносятся исключения в код.
Специализация функции
#include <iostream>
template <typename T>
T max(T a, T b) {
return (a > b) ? a : b;
}
// Специализация для типа const char*
template <>
const char* max<const char*>(const char* a, const char* b) {
return (std::strcmp(a, b) > 0) ? a : b;
}
int main() {
std::cout << "Max of 'apple' and 'banana': " << max("apple", "banana") << std::endl;
return 0;
}
Специализация класса
#include <iostream>
template <typename T>
class MyClass {
public:
T value;
MyClass(T val) : value(val) {}
void display() const {
std::cout << value << std::endl;
}
};
// Специализация для типа int
template <>
class MyClass<int> {
public:
int value;
MyClass(int val) : value(val) {}
void display() const {
std::cout << "Integer value: " << value << std::endl;
}
};
int main() {
MyClass<int> obj(42);
obj.display();
return 0;
}
Особенности и советы
- Компиляция шаблонов: Инстанцирование шаблона происходит на этапе компиляции, что может увеличить время компиляции и размер итогового бинарного файла.
- Шаблоны и заголовочные файлы: Определения шаблонов должны находиться в заголовочных файлах, чтобы компилятор мог инстанцировать шаблон в любом месте, где он используется.
- Явное указание типов: В некоторых случаях может понадобиться явно указать типы при вызове шаблона.
std::cout << max<int>(10, 20) << std::endl;