2012-05-17 15 views
55

Ho tre file. Il contenuto di main.cpp sonoriferimento non definito alla funzione modello

#include<iostream> 
#include<QString> 

#include "util.h" 

int main() 
{ 
    using Util::convert2QString; 

    using namespace std; 
    int n =22; 
    QString tmp = convert2QString<int>(n); 

    return 0; 
} 

util.h

namespace Util 
{ 
    template<class T> 
    QString convert2QString(T type , int digits=0); 
} 

util.cpp

namespace Util 
{ 
    template<class T> 
     QString convert2QString(T type, int digits=0) 
     { 
      using std::string; 

      string temp = (boost::format("%1%") % type).str(); 

      return QString::fromStdString(temp); 
     } 
} 

Quando provo a compilare questi file con seguente comando ottengo l'errore di riferimento non definito

[email protected]:~/work/trash/template$ g++ main.cpp util.cpp -lQtGui -lQtCore -I. -I/usr/local/Trolltech/Qt-4.8.0/include/QtCore -I/usr/local/Trolltech/Qt-4.8.0/include/QtGui -I/usr/local/Trolltech/Qt-4.8.0/include 
/tmp/cca9oU6Q.o: In function `main': 
main.cpp:(.text+0x22): undefined reference to `QString Util::convert2QString<int>(int, int)' 
collect2: ld returned 1 exit status 

È c'è qualcosa di sbagliato nella dichiarazione o implementazione del modello? perché ricevo questi errori di collegamento:?

risposta

88

L'implementazione di un modello non specializzato deve essere visibile a un'unità di traduzione che lo utilizza.

Il compilatore deve essere in grado di vedere l'implementazione per generare codice per tutte le specializzazioni nel codice.

questo può essere realizzato in due modi:

1) Spostare l'attuazione all'interno dell'intestazione.

2) Se si desidera tenerlo separato, spostarlo in una diversa intestazione, che si include nella vostra intestazione originale:

util.h

namespace Util 
{ 
    template<class T> 
    QString convert2QString(T type , int digits=0); 
} 
#include "util_impl.h" 

util_impl.h

namespace Util 
{ 
    template<class T> 
     QString convert2QString(T type, int digits=0) 
     { 
      using std::string; 

      string temp = (boost::format("%1") % type).str(); 

      return QString::fromStdString(temp); 
     } 
} 
+9

Molte persone usano l'estensione '.tcc' per l'implementazione del modello fi les. –

19

Hai 2 modi:

  1. Implementare convert2QString in util.h.

  2. istanziare manualmente convert2QString con int in util.cpp e definire questa specializzazione come funzione extern in util.h

util.h

namespace Util 
{ 
    template<class T> 
    QString convert2QString(T type , int digits=0); 

    extern template <> QString convert2QString<int>(int type , int digits); 
} 

util.cpp

namespace Util { 
    template<class T> 
    QString convert2QString(T type, int digits) 
    { 
     using std::string; 

     string temp = (boost::format("%1") % type).str(); 

     return QString::fromStdString(temp); 
    } 

    template <> QString convert2QString<int>(int type , int digits); 
} 
Problemi correlati