"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.

Respuestas a la pregunta(3)

Su respuesta a la pregunta