Кратко:

Инстанцирование функций-членов шаблонного класса происходит при их использовании. Компилятор генерирует конкретный код для функций-членов при компиляции, основываясь на типах, переданных шаблону.

Виды инстанцирования

  • Неявное инстанцирование: происходит автоматически при использовании шаблонного класса или его функций.
  • Явное инстанцирование: может быть использовано для оптимизации и сокращения времени компиляции, когда шаблон используется многократно с одним и тем же типом.

Разделение реализации и определения

Шаблонные классы и их функции обычно определяются в заголовочных файлах, так как компилятору нужно видеть реализацию, чтобы инстанцировать шаблон с конкретным типом.


Пример кода

  • В 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;
}