Кратко
Инстанцирование шаблона в 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;