¿Por qué obtengo errores de “símbolo externo no resuelto” cuando uso plantillas?

Cuando escribo código C ++ para una clase usando plantillas y divido el código entre un archivo fuente (CPP) y un archivo de cabecera (H), recibo un montón de errores de “símbolos externos no resueltos” cuando se trata de vincular el ejecutor final, a pesar de que el archivo objeto está correctamente construido e incluido en el enlace. ¿Qué está pasando aquí y cómo puedo solucionarlo?

Las clases y funciones con plantilla no se instancian hasta que se utilizan, normalmente en un archivo .cpp separado (por ejemplo, la fuente del progtwig). Cuando se utiliza la plantilla, el comstackdor necesita el código completo para que esa función pueda construir la función correcta con el tipo apropiado. Sin embargo, en este caso, el código para esa función se detalla en el archivo fuente de la plantilla y, por lo tanto, no está disponible.

Como resultado de todo esto, el comstackdor simplemente asume que está definido en otra parte y solo inserta la llamada a la función de plantilla. Cuando se trata de comstackr el archivo fuente de la plantilla, el tipo de plantilla específica que se está utilizando en el origen del progtwig no se usa allí, por lo que aún no generará el código requerido para la función. Esto da como resultado el símbolo externo sin resolver.

Las soluciones disponibles para esto son:

  1. incluir la definición completa de la función miembro en el archivo de encabezado de la plantilla y no tener un archivo fuente para la plantilla,
  2. definir todas las funciones miembro en el archivo fuente de la plantilla como “en línea”, o
  3. defina las funciones de miembro en la fuente de la plantilla con la palabra clave “exportar”. Lamentablemente, esto no es compatible con muchos comstackdores. (Actualización: esto se ha eliminado del estándar a partir de C ++ 11 ).

Ambos, 1 y 2, básicamente resuelven el problema al dar acceso al comstackdor al código completo para la función de plantilla cuando está intentando construir la función tipeada en el origen del progtwig.

Otra opción es colocar el código en el archivo cpp y en el mismo archivo cpp agregar instancias explícitas de la plantilla con los tipos que espera utilizar. Esto es útil si sabes que solo vas a usarlo para un par de tipos que conoces de antemano.

Para cada archivo que incluya el archivo .h, debe insertar ambas líneas:

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

muestra

 #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); . . } 

Además, no olvide colocar su clase de statement entre las constantes de centinela

 #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