Por que recebo erros de “símbolo externo não resolvido” ao usar modelos?

Quando escrevo código C ++ para uma class usando modelos e divido o código entre um arquivo de origem (CPP) e um arquivo de header (H), recebo um monte de erros de “símbolo externo não resolvido” quando se trata de vincular o executável final. apesar do arquivo de object estar sendo construído corretamente e incluído na vinculação. O que está acontecendo aqui e como posso consertar isso?

Classes e funções modeladas não são instanciadas até que sejam usadas, normalmente em um arquivo .cpp separado (por exemplo, a origem do programa). Quando o modelo é usado, o compilador precisa do código completo para que essa function possa construir a function correta com o tipo apropriado. No entanto, neste caso, o código para essa function é detalhado no arquivo de origem do modelo e, portanto, indisponível.

Como resultado de tudo isso, o compilador apenas assume que está definido em outro lugar e apenas insere a chamada para a function modelada. Quando se trata de compilar o arquivo de origem do modelo, o tipo de modelo específico que está sendo usado na origem do programa não é usado lá, portanto, ele ainda não gera o código necessário para a function. Isso resulta no símbolo externo não resolvido.

As soluções disponíveis para isso são:

  1. include a definição completa da function de membro no arquivo de header do modelo e não ter um arquivo de origem para o modelo,
  2. definir todas as funções de membro no arquivo de origem do modelo como “inline” ou
  3. defina as funções de membro na origem do modelo com a palavra-chave “export”. Infelizmente isso não é suportado por muitos compiladores. (Atualização: isso foi removido do padrão a partir do C ++ 11. )

Ambos 1 e 2 basicamente abordam o problema, dando ao compilador access ao código completo para a function modelada quando ele está tentando criar a function tipificada na origem do programa.

Outra opção é colocar o código no arquivo cpp e no mesmo arquivo cpp adicionar instanciações explícitas do modelo com os tipos que você espera usar. Isso é útil se você sabe que só vai usá-lo para alguns tipos que você conhece antecipadamente.

Para cada arquivo que inclua o arquivo .h, você deve inserir as duas linhas:

 #include "MyfileWithTemplatesDeclaration.h" #include "MyfileWithTemplatesDefinition.cpp" 

amostra

 #include "list.h" #include "list.cpp" //<---for to fix bug link err 2019 int main(int argc, _TCHAR* argv[]) { list my_list; my_list.add_end(3); . . } 

também, você não se esqueça de colocar sua class de declaração entre as constantes do centinel

 #ifndef LIST_H #define LIST_H #include  . . template  class list { private: int m_size, m_count_nodes; T m_line; node *m_head; public: list(void); ~list(void); void add_end(T); void print(); }; #endif