c ++ template e header files

Così, ho sentito che i modelli C ++ non dovrebbero essere separati in file header (.h) e source (.cpp).

Ad esempio, un modello come questo:

template  class J { T something; }; 

È vero? Perché è così?

Se a causa di ciò dovrò mettere sia la dichiarazione che l’implementazione nello stesso file, dovrei inserirla in un file .h o in un file .cpp?

Intestazioni.

È perché i modelli vengono istanziati in fase di compilazione, non in tempo di collegamento, e le diverse unità di traduzione (approssimativamente equivalenti ai tuoi file .cpp ) solo “conoscono” a vicenda durante il link-time. Le intestazioni tendono ad essere ampiamente “conosciute” in fase di compilazione perché tu le #include in qualsiasi unità di traduzione che ne abbia bisogno.

Leggi https://isocpp.org/wiki/faq/templates per ulteriori informazioni.

Il motivo per cui non è ansible inserire una class basata su modelli in un file .cpp è perché al fine di “compilare” un file .cpp è necessario sapere quale sia il tipo che viene utilizzato al posto di T. Così com’è una class basata su modelli ( come la tua class J) non ha abbastanza informazioni da compilare. Quindi deve essere tutto nelle intestazioni.

Se si desidera interrompere l’implementazione in un altro file per la pulizia, è consigliabile utilizzare un file .hxx. In questo modo: all’interno del tuo file di intestazione, Jh, inserisci:

 #ifndef _J_H__ #define _J_H__ template  class J{ // member definitions }; #include "j.hxx" #endif // _J_H__ 

e poi, in j.hxx lo avrai

 template  J::J() { // constructor implementation } template  J::~J() { // destructor implementation } template  void J::memberFunc() { // memberFunc implementation } // etc. 

Finalmente nel tuo file .cpp che usa la class basata sui modelli, chiamiamolo K.cpp avrai:

 #include "Jh" // note that this always automatically includes J.hxx void f(void) { J jinstance; // now the compiler knows what the exact type is. } 

Si è vero. La dichiarazione e l’implementazione sono generalmente inserite nel file di intestazione tutte insieme. Alcuni compilatori hanno sperimentato una parola chiave export che consentiva loro di essere separati, ma che è stato rimosso da C ++ 0x. Dai un’occhiata a questa voce delle FAQ per tutti i dettagli sporchi.

Se è necessario che il codice del modello sia utilizzabile da altre unità di traduzione (file .cpp), è necessario inserire l’implementazione nel file .h altrimenti le altre unità non saranno in grado di creare un’istanza del modello (espanderlo in base al modello tipi che usano).

Se la tua funzione template è solo istanziata in un file .cpp, puoi definirla lì. Ciò accade a volte quando una class ha una funzione membro privata che è un modello (ed è chiamata solo dal file di implementazione, non dal file di intestazione della class).