es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Solución elegante para implementar las plantillas de c++

Inspirado en esta pregunta de 2009.

Antecedentes: Actualmente estoy trabajando en un pequeño proyecto en c++ y decidí intentar crear mis propias clases con plantillas. Inmediatamente me encontré con una docena de errores de enlace.

Según mi entendimiento, las especializaciones de plantillas no se generan hasta que sea absolutamente necesario, y esto implica que la implementación de una clase con plantillas debe estar en línea o acompañada por una instancia explícita en la parte inferior. (Por qué uno implica lo otro, no estoy muy seguro)

Pregunta. ¿Por qué es así? ¿Hay algo especial en el orden de la compilación que hace imposible que el compilador instancie la plantilla bajo demanda si está implementada en un archivo .cpp separado? En mi mente, el encabezado y la implementación se simplemente se unen.

Además, la pregunta que enlacé anteriormente se publicó hace más de diez años, y algunos comentarios indican que la cita de los c++-faq mencionada está desactualizada, así que me preguntaba si los nuevos estándares admiten soluciones que permitan tanto archivos de encabezado/implementación separados como instanciación implícita.

Tags:  ,

Answer

  1. Avatar for davy.ai

    La razón por la que se requiere la implementación en línea o la instanciación explícita en la parte inferior se debe a la forma en que funcionan las plantillas en C++.

    Cuando se utiliza una clase o una función de plantilla, el compilador necesita acceso a la definición completa de la plantilla para generar el código específico para los parámetros de la plantilla dados. Esto significa que la definición de la plantilla debe estar disponible en el punto de instanciación.

    Si la definición de la plantilla se separa del archivo de encabezado e implementa en un archivo .cpp separado, el compilador generará archivos de objeto separados para cada unidad de traducción que utilice la plantilla con diferentes tipos de parámetros. Cada archivo de objeto contendrá la definición incompleta de la plantilla con los tipos de parámetros específicos, pero no contendrá la definición completa de la plantilla.

    Al enlazar estos archivos de objeto juntos, el enlazador no podrá encontrar las definiciones completas de la plantilla y, por lo tanto, generará errores de enlace.

    Por lo tanto, para asegurarse de que la definición completa de la plantilla esté disponible en cada punto de instanciación, la plantilla debe implementarse en línea en el archivo de encabezado o instanciarse explícitamente en la parte inferior del archivo de encabezado para cada posible combinación de parámetros de plantilla.

    En cuanto a la segunda parte de la pregunta, las versiones más nuevas de C++ no cambian este comportamiento. Todavía es necesario proporcionar la implementación en línea o la instanciación explícita para evitar errores de enlace. Sin embargo, algunos compiladores pueden tener extensiones u optimizaciones que permitan la instanciación implícita en ciertos casos, pero esto no es parte del estándar.

Comments are closed.