Шаблон С++, другое объявление и определение, компоновщик не может разрешить символы [дубликаты]

Выполнение простого кода шаблона, приведенного здесь; просто я пишу отдельное объявление и определение

Это мой заголовочный файл

template <typename T>
class SmartPointerGen
{
private:
        T*  pData;

public:
        SmartPointerGen(T* pValue);
        ~SmartPointerGen();

        T&  operator* ();
        T*  operator-> ();
};

Вот как я определяю методы

    #include "SmartPointer_Generic.h"

    template <typename T> 
    SmartPointerGen<T>::SmartPointerGen(T* pValue) :    pData(pValue)
    {

    }

    template <typename T>
    SmartPointerGen<T>::~SmartPointerGen()
    {
        delete pData;
    }

    template <typename T>
    T&  SmartPointerGen<T>::operator* ()
    {
        return *pData;
    }

    template <typename T>
    T*  SmartPointerGen<T>::operator-> ()
    {
        return pData;
    }

И в main() я пытаюсь использовать то же самое с

SmartPointerGen<Person> pPersonGen(new Person("WTF Again"));

Я считаю, что проблема связана с определением класса SmartPointerGen, я пытался следовать этому синтаксис для определения шаблонных методов вне класса, но компоновщик говорит о неразрешенных символах для деструктора и перегруженных операторов (НО НЕ ДЛЯ КОНСТРУКТОРА).

ошибки: (показаны только 1, остальные очень похожи)

main.obj : error LNK2019: unresolved external symbol "public: __thiscall SmartPointerGen<class Person>::SmartPointerGen<class Person>(class Person *)" (??0?$SmartPointerGen@VPerson@@@@QAE@PAVPerson@@@Z) referenced in function _main


person oh_dear_i_love_coding    schedule 12.02.2014    source источник


Ответы (1)


Вы должны определить шаблоны в том же заголовочном файле, в котором они были объявлены - это языковое ограничение.

person Arsenii Fomin    schedule 12.02.2014
comment
означает..? не совсем понял вас. Я имею в виду, что я не могу написать класс в заголовочном файле и определить метод. в каком-то другом файле? Так ли это, потому что для шаблонов требуется двухэтапная компиляция? - person oh_dear_i_love_coding; 12.02.2014
comment
означает: весь код должен находиться в заголовочном файле, без CPP для шаблонов (если вы не включите файлы CPP) - person Ferenc Deak; 12.02.2014
comment
да, весь код шаблона должен быть в заголовочном файле. - person Arsenii Fomin; 12.02.2014
comment
Не обязательно в одном файле. Это может быть где угодно, если определение видно в каждом файле, использующем шаблон. - person Angew is no longer proud of SO; 12.02.2014
comment
Поскольку это ответ, с которым я согласен, если вы заранее знаете, какие типы данных будут использовать шаблоны (то есть - это не библиотека), вы можете посмотреть это ТАК вопрос и ответы - person Sigi; 12.02.2014
comment
Причина в том, что специализации шаблонов генерируются по требованию. Например, у вас есть контейнер vector‹T›. Если в вашей программе нет векторов, код шаблона не генерируется. Если у вас есть вектор‹int›, будет сгенерирована специализация вектора int. Это становится очень важным, если вы пишете библиотеку. С одной стороны, вы не можете хранить весь возможный код специализации шаблона в объектных файлах библиотеки (он бесконечен). С другой стороны, у вас уже должен быть весь объектный код для предоставления пользователям вашей библиотеки. Это парадокс. - person Arsenii Fomin; 12.02.2014