Кратко

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