Шаблонные классы в C++ обычно полностью определяются в заголовочных файлах (.h/.hpp), потому что:
Механизм работы шаблонов:
Ограничения линковщика:
// mytemplate.h
template <typename T>
class MyTemplate {
public:
void doSomething(T value);
};
// mytemplate.cpp
template <typename T>
void MyTemplate<T>::doSomething(T value) { /* реализация */ }
При таком подходе:
Можно явно указать, для каких типов нужно создать инстанциации:
// mytemplate.h
template <typename T>
class MyTemplate {
public:
void doSomething(T value);
};
// mytemplate.cpp
#include "mytemplate.h"
template <typename T>
void MyTemplate<T>::doSomething(T value) { /* реализация */ }
// Явное инстанцирование для нужных типов
template class MyTemplate<int>;
template class MyTemplate<double>;
template class MyTemplate<std::string>;
Плюсы:
Минусы:
// mytemplate.h
template <typename T>
class MyTemplate {
public:
void doSomething(T value);
};
#include "mytemplate_impl.h" // или mytemplate.cpp
Плюсы:
Минусы:
C++98 предлагал ключевое слово export
, но:
Для библиотек с известным набором типов:
Для общих библиотек:
Оптимизация времени компиляции:
// mytemplate.h
#pragma once
template <typename T>
class MyTemplate {
public:
void doSomething(T value);
private:
void helperMethod(T value);
};
// Явное объявление инстанциаций
extern template class MyTemplate<int>;
extern template class MyTemplate<double>;
// mytemplate_impl.h
#include "mytemplate.h"
template <typename T>
void MyTemplate<T>::doSomething(T value) {
helperMethod(value);
}
template <typename T>
void MyTemplate<T>::helperMethod(T value) {
// реализация
}
// mytemplate.cpp
#include "mytemplate_impl.h"
// Явное инстанцирование
template class MyTemplate<int>;
template class MyTemplate<double>;
// mytemplate.ixx
export module mytemplate;
export template <typename T>
class MyTemplate {
public:
void doSomething(T value) { /* реализация */ }
};
Резюмируем: хотя традиционно шаблонные классы полностью определяются в заголовочных файлах, существуют методы для частичного разделения объявления и реализации. Выбор подхода зависит от конкретного случая использования и требований проекта. Современные стандарты C++ предлагают новые возможности для более эффективной работы с шаблонами.