¿Por qué recibo errores de "símbolos externos no resueltos" cuando uso plantillas? [duplicar]
Cuando escribo código C++ para una clase usando plantillas y divido el código entre un archivo fuente (CPP) y un archivo de encabezado (H), obtengo una gran cantidad de errores de "símbolos externos no resueltos" cuando se trata de vincular el ejecutable final. a pesar de que el archivo objeto se creó e incluyó correctamente en el enlace. ¿Qué está pasando aquí y cómo puedo solucionarlo?
Las clases y funciones con plantilla no se crean instancias hasta que se utilizan, generalmente en un archivo .cpp separado (por ejemplo, el código fuente del programa). Cuando se utiliza la plantilla, el compilador necesita el código completo de esa función para poder crear 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 compilador simplemente asume que está definido en otro lugar y solo inserta la llamada a la función con plantilla. Cuando se trata de compilar el archivo fuente de la plantilla, el tipo de plantilla específico que se está usando en el código fuente del programa 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:
- 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,
definir todas las funciones miembro en el archivo fuente de la plantilla como "en línea"(Actualización: [esto no funciona en Visual Studio 2017+]), odefina las funciones miembro en el código fuente de la plantilla con la palabra clave "exportar". Lamentablemente, esto no es compatible con muchos compiladores.(Actualización: esto se eliminó del estándar a partir de C++11 ).
Tanto 1 como 2 básicamente abordan el problema al darle al compilador acceso al código completo de la función con plantilla cuando intenta construir la función escrita en el código fuente del programa.
Otra opción es poner 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 usar. Esto es útil si sabes que solo lo usarás para un par de tipos que conoces de antemano.