LNK2019 ошибка неразрешенного внешнего символа

я решил создать список (по практическим соображениям, так что отвали меня от вопроса об изобретении колеса, спасибо ..)

Я получил эту ОШИБКУ LNK2019, и я верю ее специфическому коду, потому что я, кажется, не могу найти способ исправить это (да, я тут зарегился)

Я обнаружил, что проблом вызван потому, что компилятор не распознает определения методов, но я не могу понять, почему.
Я использую MVS 2010, поэтому аргументы ссылки делаются автоматически. вот мой код

Список H:

#ifndef _DLIST
#define _DLIST

#include "Node.h"
template<class DataO>
class Dlist
{
private:
/* Data Members */
Node<DataO>* _ndHead;
Node<DataO>* _ndTail;
unsigned int   _nLength;

/* Methods */
void Delete();

public:
/* Ctors && Dtors */
Dlist();
~Dlist();

/* Getters && Setters */
int Length();

/* Methods */
void Add(DataO doData);
void Clear();
void RemoveAt(unsigned int nIndex);
void Remove();
};

#endif

Список Cpp:

// Dlist.cpp

#include "Dlist.h"
/* ------------------ Dlist Section ------------------ */
/* --- Constracturs && Destractur --- */
template<class DataO>
Dlist<DataO> :: Dlist()
{
// Init data
this->_ndHead = NULL;
this->_ndTail = NULL;
this->_nLength = 0;
}

template<class DataO>
Dlist<DataO> :: ~Dlist()
{
// Check if we have nodes to delete
if (this->_nLength > 0);
{
this->Clear();
}
}

/* --- Methods -- */
template<class DataO>
int Dlist<DataO> :: Length()
{
// Return the length
return (this->Length);
}
template<class DataO>
void Dlist<DataO> :: Add(DataO doData)
{
// Check if head is null
if (this->_ndHead == NULL)
{
// Create head
this->_ndHead = new Node<DataO>(doData, NULL, NULL);
}
// Check if tail is null
else if (this->_ndTail == NULL)
{
// Create tail
this->_ndTail = new Node<DataO>(doData, NULL, this->_ndHead);

// Set head's next
this->_ndHead->SetNext(this->_ndTail);
}
// Create a new Node and replace the tail.
else
{
// Create a new node.
this->_ndTail->_ndNext = new Node<DataO>(doData, NULL, this->_ndTail);

// Make the new node the tail
this->_ndTail = this->_ndTail->_ndNext;
}
}

Узел Н:

    template<class DataO>
class Node
{
private:
/* Data Members */
DataO  _doData;
Node<DataO>*  _ndPrev;
Node<DataO>*  _ndNext;

/* Methods */
void Delete();

public:
/* Ctors && Dtors */
Node<DataO>(DataO doData);
Node<DataO>(DataO doData, const Node& ndNext, const Node& ndPrev);
~Node();

/* Getters && Setters */
DataO&  GetData();
void    SetData(DataO doData);

const Node& GetNext();
void  SetNext(const Node* ndNextNode);
const Node& GetPrev();
void  SetPrev(const Node* ndPrevNode);
};

Узел Cpp:

// Node.cpp

#include "Node.h"
/* ------------------ Node Section ------------------ */
/* --- Constracturs --- */
template<class DataO>
Node<DataO> :: Node(DataO doData)
{
// Init data
this->SetData(doData);
this->SetNext(NULL);
this->SetPrev(NULL);
}

template<class DataO>
Node<DataO> :: Node(DataO doData, const Node& ndNext, const Node& ndPrev)
{
// Init data
this->SetData(doData);
this->SetNext(ndNext);
this->SetPrev(ndPrev);
}

/*
-   Node destructor -
-   Maneges the change of nodes.
-   Changes the Previous node next node,
-   to the current node next node.
*/
template<class DataO>
Node<DataO> :: ~Node()
{
// Check that prev is not null
if (this->GetPrev != NULL)
{
// Set prevs Next to current next
this->GetPrev().SetNext(this->GetNext());
}
}

/*
-   GetData -
-   Returns the data stored in the Node.
*/
template<class DataO>
DataO& Node<DataO> :: GetData()
{
// Return the data
return (this->_doData&);
}

/*
-   SetData -
-   Sets the data stored in the Node.
*/
template<class DataO>
void Node<DataO> :: SetData(DataO doData)
{
// Sets data
this->_doData = doData;
}

/*
-   GetNext -
-   Returns the next node in the list.
*/
template<class DataO>
const Node<DataO>& Node<DataO> :: GetNext()
{
// Returns the next node in the list.
return (this->_ndNext&);
}

/*
-   SetNext -
-   Set the next node in the list.
*/
template<class DataO>
void Node<DataO> :: SetNext(const Node* ndNextNode)
{
// Set next node as given node
this->_ndNext = ndNextNode;
}

/*
-   GetPrev -
-   Returns the previous node in the list.
*/
template<class DataO>
const Node<DataO>& Node<DataO> :: GetPrev()
{
// Returns the next node in the list.
return (this->_ndPrev&);
}

/*
-   SetPrev -
-   Set the previous node in the list.
*/
template<class DataO>
void Node<DataO> :: SetPrev(const Node* ndPrevNode)
{
// Set next node as given node
this->GetPrev = ndPrevNode;
}

1

Решение

Это происходит потому, что компилятор MSVC не поддерживает внешний шаблон. Я вижу вашу идею, это был бы правильный подход, но он не работает с большинством компиляторов. Это связано с тем, что компилятор должен иметь доступ ко всему определению шаблона (а не только к сигнатуре), чтобы генерировать код для каждого экземпляра шаблона. У вас есть 2 варианта, чтобы заставить его работать:

  1. Определите все методы в заголовочном файле (как большинство библиотек Boost)

  2. Явно создайте экземпляр класса шаблона для предопределенных типов (таким образом, ваш класс не будет универсальным)

Смотрите подробное объяснение Вот

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]