"Definición múltiple" cuando se utilizan archivos de encabezado (simulados) para plantillas
Soy consciente de que las definiciones de funciones con plantilla de C ++ deben colocarse en los archivos de encabezado. Sin embargo, por razones de mejor legibilidad y estructura de una (potencialmente) gran biblioteca que estoy haciendo,Separé las declaraciones de las implementaciones, en encabezados "simulados" (cual#include
los archivos de implementación, comoesta estructura de archivos).Tenga en cuenta que soy consciente de que elSe debe incluir la implementación de funciones con plantilla en tiempo de compilación, y estoy haciendo eso.
En breve,Tengo un error de "definición múltiple" cuando agrego una declaración de función sin plantilla en el archivo de implementación. La explicación larga con ejemplos sigue.
Cuando el par de encabezado "simulado" + archivos de implementaciónsolo contiene el par declaración / implementación de la función con plantillaTodo funciona bien. También funciona bien cuandoAgrego una implementación de una nueva función con plantilla solo en el archivo de implementación.
Ejemplo de trabajo (lo haría#include "algo.h"
en mimain.cpp
cuando quería usar esta funcionalidad):
Archivo de encabezado "simulado" algo.h:
#ifndef ALGO_H
#define ALGO_H
namespace fl{
template <typename Compare>
void algo(.. non-templated args .., Compare order = std::less<int>());
}
#include "tpp/algo.cpp"
#endif // ALGO_H
Archivo de implementación tpp / algo.cpp: (actualmente soloalgo.tpp)
Nota: Utilizando latpp/.cpp
el archivo estaba en la versión inicial, ahora estoy usando un.tpp
archivo por@ πάντα ῥεῖSugerencia, explicación al final.
#ifndef TPP_ALGO
#define TPP_ALGO
#include "../algo.h"
namespace fl{
template <typename Compare>
void subFunctionality(Compare order, .. args ..){ /* impl */ }
template <typename Compare>
void algo(.. non-templated args .., Compare order){
subFunctionality(order, .. args ..);
// implementation
}
}
#endif // TPP_ALGO
Surge el problemacuando agrego una implementación de función sin plantilla en el archivo de implementación. (No funciona) ejemplo de latpp / algo.cpp (actualmente soloalgo.tpp) (usando el mismoalgo.h):
#ifndef TPP_ALGO
#define TPP_ALGO
#include "../algo.h"
namespace fl{
template <typename Compare>
void subFunctionality(Compare order, .. args ..){ /* impl */ }
void moreSubFun(.. args ..) { /* impl */ }
template <typename Compare>
void algo( .. non-templated args ..., Compare order){
subFunctionality(order, .. args ..);
moreSubFun(.. args ..);
// more stuff
}
}
#endif // TPP_ALGO
Consigo el"definición múltiple" error (desde donde lo incluí enmain.cpp
), al igual que:
obj/Release/main.o In function `fl::moreSubFun(...)':
main.cpp multiple definitions of `fl::moreSubFun(..)'
obj/Release/../tpp/algo.o:algo.cpp first defined here
¿Por qué sucede esto solo a las funciones sin plantilla, mientras que funciona bien para las plantillas?, y más importante,¿Cómo resuelvo este problema?
Miré por todas partes SO, y no puedo encontrar nada útil :( Idealmente, estoy buscando algo lo más cercano posible a mi propia estructura de archivos (pero tomaré todo lo que funcione mientras sigo usando alguna separación en "simulacro" ".h
+ tpp/.cpp
) ¿Tengo que sacar las subfuncionalidades adicionales en un par de plantillas separadas y sin plantilla?.h/.cpp
archivos, o hay otras soluciones? (Las subfuncionalidades idealmente no deberían ser visibles para el usuario final).
Soy reacio a usarinline
al definirfl::moreSubFunc(..)
ya que la función es bastante grande (y me enseñaroninline
idealmente solo debe usarse con funciones pequeñas). Esto resuelve el problema, pero estoy buscando ver si hay una solución diferente.
Estoy trabajando enCode::Blocks
, utilizandogcc version 4.7.2
. Esta es la razón inicial por la que mi archivo de implementación estpp/.cpp
(.cpp
extensión), ya queCode::Blocks
no lo admite por defecto. Esto se cambia en la implementación actual siguiente@ πάντα ῥεῖsugerencia de (mira abajo).
Edición tardía (Después de que enseñé se encontró la solución) EnseñéRespuesta de @ πάντα ῥεῖ resuelve el problema PellizquéCode::Blocks
aceptar.tpp
archivos (ya sea tratándolo comoencabezamiento ofuente archivos). Inicialmente, esta solución funcionó.
Sin embargo,esta solución funcionó solo cuando elalgo.h el archivo se incluyó en solo otro archivo: cuando lo incluí solo enmain.cpp. Sin embargo, tan pronto como intenté incluirlo en otro archivo fuente (p. Ej.algo2.cpp) que usarían esos algoritmos (además demain.cpp), eldefinición múltiple El problema volvió.
Línea de fondo,el problema persiste tan pronto como incluyo elalgo.h en más de un archivo, y sigo buscando una solución.