Libreria condivisa C ++ con modelli: errore di simboli non definiti

Sto cercando di collegarmi a una libreria condivisa con una class template, ma mi sta dando errori “simboli non definiti”. Ho condensato il problema a circa 20 righe di codice.

shared.h

template  class myclass { Type x; public: myclass() { x=0; } void setx(Type y); Type getx(); }; 

shared.cpp

 #include "shared.h" template  void myclass::setx(Type y) { x = y; } template  Type myclass::getx() { return x; } 

main.cpp

 #include  #include "shared.h" using namespace std; int main(int argc, char *argv[]) { myclass m; cout << m.getx() << endl; m.setx(10); cout << m.getx() << endl; return 0; } 

Ecco come compilo la libreria:

 g++ -fPIC -c shared.cpp -o shared.o g++ -dynamiclib -Wl,-dylib_install_name -Wl,libshared.dylib -o libshared.dylib shared.o 

E il programma principale:

 g++ -c main.cpp g++ -o main main.o -L. -lshared 

Solo per ottenere i seguenti errori:

 Undefined symbols: "myclass::getx()", referenced from: _main in main.o _main in main.o "myclass::setx(int)", referenced from: _main in main.o 

Se rimuovo il materiale ‘template’ in shared.h/cpp , e li sostituisco con solo ‘int’, tutto funziona correttamente. Inoltre, se faccio solo copia e incolla il codice di class template in main.cpp e non mi main.cpp alla libreria condivisa, tutto funziona allo stesso modo.

Come posso ottenere una class template come questa per funzionare attraverso una libreria condivisa?

Sto usando MacOS 10.5 con GCC 4.0.1.

Oltre alle altre risposte, puoi istanziare esplicitamente classi di modelli. Ciò è utile solo se si conoscono in anticipo i tipi che i parametri del modello possono assumere. Si istanzia il modello con tutti questi tipi nella libreria.

Per compilare il tuo esempio, aggiungi quanto segue alla fine di shared.cpp :

 // Instantiate myclass for the supported template type parameters template class myclass; template class myclass; 

Questo istanzia il modello con Type = int e posiziona il codice istanziato nella libreria condivisa. Aggiungi tutte le istanze esplicite di cui hai bisogno, per tutti i tipi di cui hai bisogno.

Anche in questo caso, se si desidera essere in grado di creare un’istanza del modello con qualsiasi parametro di tipo arbitrario, è necessario aggiungere le definizioni al file di intestazione, in modo che il compilatore conosca il codice sorgente del modello durante l’istanziazione in altre unità di compilazione.

Le definizioni delle funzioni del modello devono risiedere nei file di intestazione. Sposta le definizioni da shared.cpp a shared.h.

Quindi, non è ansible compilarlo in una libreria condivisa e quindi collegarsi ad esso. Semplicemente non funziona così.

È necessario includere anche l’implementazione delle classi template nei file header. Questo è un vincolo di modelli in C ++. Quindi includi shared.cpp da main (#include) o sposta semplicemente il codice da shared.cpp in shared.h

Il compilatore deve vedere tutto il codice per un modello, in modo che possa generare il codice appropriato per il tipo effettivo che si desidera utilizzare. Quindi dovresti inserire tutto il codice nel tuo .h. file.