Как создать шаблон класса в .h .cpp файлах?

Пишу Vector3, который хранит переменные X Y Z типа T. Написал вот такой header файл:

//3 diserminal vector
#ifndef VOXELENGINE_VECTOR3_H
#define VOXELENGINE_VECTOR3_H

template<class T>
class Vector3 {
public:
    T X;
    T Y;
    T Z;
    Vector3(T X, T Y, T Z);
    ~Vector3();
};


#endif //VOXELENGINE_VECTOR3_H

Но как теперь реализовать этот шаблон класса в .cpp файле? Вот так не получается:

#include "Vector3.h"
Vector3::Vector3(T X, T Y, T Z){
    Vector3::X = X;
    Vector3::Y = Y;
    Vector3::Z = Z;
}

Ошибки: неизвестный тип 'T' Vector3 не является классом, namrspace или enumenartion

Как мне создать .cpp файл для шаблона класса? Или шаблоны вообще нельзя писать в заголовочных файлах?


Ответы (1 шт):

Автор решения: AlexGlebe

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

Vector3.h

//3 diserminal vector
#ifndef VOXELENGINE_VECTOR3_H
#define VOXELENGINE_VECTOR3_H

template<class T>
class Vector3 {
public:
    T X;
    T Y;
    T Z;
    Vector3(T X, T Y, T Z);
    // деструктор пока не надо переделывать
    // ~Vector3();
};

// реализация всегда присутствует для всех типов и
// для всех компилируемых файлов
// в более сложных ситуациях (циклических связей шаблонов)
// подключайте "Vector3-impl.h" в '.cpp' файлах
# include "Vector3-impl.h"

#endif //VOXELENGINE_VECTOR3_H

Vector3-impl.h

#ifndef VOXELENGINE_VECTOR3_IMPL_H
#define VOXELENGINE_VECTOR3_IMPL_H

// реализация шаблонов должна начинаться на слове template
// с именем типа T и типы Vector3 должны всегда с добавлением
// шаблонного типа T заключённого в угловых скобках
template  <class  T>
Vector3<T>::Vector3(T X, T Y, T Z){
    Vector3<T>::X = X;
    Vector3<T>::Y = Y;
    Vector3<T>::Z = Z;
}

# endif // VOXELENGINE_VECTOR3_IMPL_H

main.cpp

// g++ -Wall -Wextra -Wpedantic -Winline -std=c++17 main.cpp -o main
# include "Vector3.h"
int main  ( ) {
  Vector3 < int > v3  (1,2,3)  ;
  Vector3 < double > vd  (1,2,3)  ;
}
→ Ссылка