Newsgroup: it.comp.lang.c++
Titolo: Template: problemi con il linker

Ciao  a tutto il NG,
il mio problema è questo:
ho definito un template di classe in un file '.h', mentre la definizione 
delle funzioni proprie l'ho spostata in un file '.cpp' (sono troppe per 
averle nell'header, diventa letteralmente illegibile); 
quando effettuo la compilazione del progetto che usa il template di classe 
(sto usando il GCC  sotto Linux --> gcc -c <file-1.cpp>... <file-n.cpp>), 
tutto fila per il verso giusto;
ma quando provo a generare l'eseguibile ottengo un errore dal linker... in 
pratica non riesce a trovare la definizione delle funzioni che uso, ma 
relative all'istanza del template di classe; il tutto si risolve se la 
definizione delle funzioni la faccio nel corpo del template di classe (come 
ho sempre fatto :-)) ) oppure se (sbagliatissimo) includo assieme 
all'header il file '.cpp' in cui ho definito 'ste benedette funzioni. Mi 
spiego meglio con un breve esempio:
//nell'header
//direttive isolamento e bla bla bla
template <class T>
class A {
public:
A();
~A();
void FaQualcosa();
.
.
.
};
//nel file .cpp
#include "header di sopra"
template <class T>
A<T>::A() { . . . }
template <class T>
A<T>::~A() { . . . }
ecc. ecc.
se avessi:
A istanza1<char>;
A istanza2<int>;
ottengo:
unable to resolve symbol A<char>::A() in file <file oggetto>.o
e
unable to resolve symbol A<int>::A() in file ....
e così di seguito per tutte le funzioni del template che uso per una data 
istanza...
Mi sono spulciato il Lippman e ho trovato che dovevo definire il template 
come esportato con "extern"; l'ho fatto... ma quando compilo ottengo che la 
direttiva "extern" non è implementata e quindi viene ignorata???!!!! di 
seguito non cambia nulla con il linker....
Dove sbaglio??? non ho provato con altri compilatori xché l'applicativo deve 
girare sotto Linux ed ho solo il GCC. Nel manuale del GCC ho trovato le 
direttive #pragma interface per l'header (se non ho capito male) e #pragma 
implementation <nome file che implementa>; le ho provate ... ma i risultati 
sono stati gli stessi (ammesso che non abbia commesso errori). Ci sono poi 
una serie di parametri da usare quando ci sono i template... ma la mia 
versione del compilatore li considera deprecati e semplicemente non ottengo 
i risultati sperati; sul sito della FSF non c'è un manuale più aggiornato 
(quello che ho scaricato è il + nuovo).
Grazie a tutti, ciao. S.

averle nell'header, diventa letteralmente illegibile); 
quando viene definita una classe template, è necessario oltre alla
dichiarazione inserire nell'header stesso anche il corpo delle
funzioni/metodi template...
Antonio

Antonio Mazzeo wrote:

Si ma ci sono due metodi di compilazione, per separazione e per inclusione; 
quello per inclusione corrisponde a quello che dici tu (e che ho sempre 
usato anch'io) mentre l'altro consente di separare le dichiarazioni dalle 
definizioni (xrò non sono sicuro che funga anche su file diversi :-(( ).
Il mio problema è che la classe diventa illegibile perché le funzioni sono 
molto lunghe... potrei fare anche senza template, ma mi semplificherebbero 
di molto la vita :-))
Ciao e grazie. S.

 ha scritto nel messaggio
news:MsML8.12675$K4.2...@twister2.libero.it...

Usando i template devi per forza dichiarare ed implementare tutto nello
stesso file header.
--
ciao,
Cecco
---------
Visit: 
www.sourceforge.net/projects/dlab
Home Page: 
http://dlab.sourceforge.net/
Dlab-developer mailing list
https://lists.sourceforge.net/lists/listinfo/dlab-developer

 sono molto lunghe... 
Il fatto che le definizioni dei metodi di una classe template debbano
essere visibili in ogni unità di compilazione che debba instanziarli non
implica automaticamente che esse debbano essere inserite nella
dichiarazione della classe, né che debbano comparire nello stesso file
header. Distribuire dichiarazione e definizioni in due file distinti è
comunque possibile, a condizione che vangano entrambi #inclusi durante la
compilazione.
--  file A.h
 #ifndef A_h_guard
 #define A_h_guard
 template < class T >
  class A {
       public:
       void func();
  };
 #include "A_impl.h"
 #endif
-- file  A_impl.h
 template< class T >
  void A<T>::func()
  {
         /* ... */
  }
 
Max
 
 

 definizioni (xrò non sono sicuro che funga anche su file diversi :-(( ).
Il metodo "per separazione" definito dallo standard si basa sul
meccanismo di export dei template che attualmente disponibile al
pubblico solo nella versione online del compilatore Comeau. Altri
compilatori possono fornire soluzioni alternative, ma comunque non
standard.
Ciao,
Nicola

Nicola Musatti wrote:

Ciao grazie a tutti,
ho afferrato il concetto, non è proprio possibile avere un compilatore che 
supporti tutto...
S.