Можно ли и нужно ли выносить определение метода шаблонного класса в .cpp файл?
У меня есть шаблонный класс и его конструктор. Для обычных классов я пишу объявления в .hpp файле и определения к ним в .cpp файле. На сколько правильным будет делать такой вынос определения в .cpp файл в случае с конструктором шаблонного классам или другими его методами? Я пробовал реализовывать это примерно так (вроде бы работает, но громоздко):
// .hpp
...ъх
template<typename type>
class NAME
{
public:
NAME(type arg);
};
// .cpp
...
template<typename type>
NAME<type>::NAME(type arg)
{
// определение
}
На некоторых форумах люди говорят, что правильнее оставлять определение в заголовочном классе. Но как по мне, это будет сильно ломать всю структуру проекта. Или не будет?
Спасибо!
Ответы (1 шт):
Пока шаблон не инстанцирован - класса не существует, поэтому он должен быть в хэдере. Вы его просто не сможете создать в сорсах. Точнее, вы его не сможете в этом случае объявлять в других файлах, т.е. разделяемый шаблон обязательно должен быть в хэдере.
Вы можете выносить определение метода шаблона класса за скобки, но от этого метод не перестаёт быть частью этого шаблона.
В сорсах может быть только явное или неявное инстанцирование шаблона:
#include <vector>
// explicit template instantiation
template class std::vector<short>;
// Не путать со специализацией
// full template specialization
// template<> class MyVector<short> { ... };
int main() {
// implicit template instantiation
std::vector<int> vector;
return 0;
}
На самом деле, начиная с C++17 ключевое слово inline по сути стало указанием компилятору, что объект должен быть объявлен один раз (ODR). И вы можете выносить определения методов за скобки просто добавив спецификатор inline (не имеет смысла для шаблона), написав таким образом header-only библиотеку.
Иными словами, определение методов класса вовсе не обязательно выводить в файл сорсов даже если класс не шаблонный, а для шаблона класса так делать вообще нельзя.