Кратко:
Инстанцирование функций-членов шаблонного класса происходит при их использовании. Компилятор генерирует конкретный код для функций-членов при компиляции, основываясь на типах, переданных шаблону.
Виды инстанцирования
- Неявное инстанцирование: происходит автоматически при использовании шаблонного класса или его функций.
- Явное инстанцирование: может быть использовано для оптимизации и сокращения времени компиляции, когда шаблон используется многократно с одним и тем же типом.
Разделение реализации и определения
Шаблонные классы и их функции обычно определяются в заголовочных файлах, так как компилятору нужно видеть реализацию, чтобы инстанцировать шаблон с конкретным типом.
Пример кода
- В Stack.hопределен шаблонный классStackс декларацией всех функций-членов.
- В Stack.tppреализованы все функции-члены шаблонного класса.
- В main.cppиспользуется шаблонный классStackдля типаint.
Определение шаблонного класса в заголовочном файле (Stack.h)
#ifndef STACK_H
#define STACK_H
 
#include <vector>
#include <stdexcept>
 
template<typename T>
class Stack {
private:
    std::vector<T> elements;
 
public:
    void push(const T& value);
    void pop();
    T top() const;
    bool isEmpty() const;
    size_t size() const;
};
 
#include "Stack.tpp" // Включение файла с реализацией шаблонных функций
 
#endif // STACK_HРеализация функций-членов шаблонного класса в отдельном файле (Stack.tpp)
template<typename T>
void Stack<T>::push(const T& value) {
    elements.push_back(value);
}
 
template<typename T>
void Stack<T>::pop() {
    if (!elements.empty()) {
        elements.pop_back();
    } else {
        throw std::out_of_range("Stack<>::pop(): empty stack");
    }
}
 
template<typename T>
T Stack<T>::top() const {
    if (!elements.empty()) {
        return elements.back();
    } else {
        throw std::out_of_range("Stack<>::top(): empty stack");
    }
}
 
template<typename T>
bool Stack<T>::isEmpty() const {
    return elements.empty();
}
 
template<typename T>
size_t Stack<T>::size() const {
    return elements.size();
}Использование шаблонного класса в файле (main.cpp)
#include <iostream>
#include "Stack.h"
 
int main() {
    Stack<int> intStack;
 
    intStack.push(1);
    intStack.push(2);
    intStack.push(3);
 
    std::cout << "Top element: " << intStack.top() << std::endl; // Вывод: 3
 
    intStack.pop();
    std::cout << "Top element after pop: " << intStack.top() << std::endl; // Вывод: 2
 
    std::cout << "Stack size: " << intStack.size() << std::endl; // Вывод: 2
 
    return 0;
}