2012-05-17 16 views
55

Ich habe drei Dateien. Der Inhalt von main.cpp sindundefined Verweis auf Vorlagenfunktion

#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); 
     } 
} 

Wenn ich versuche, diese Dateien mit folgenden Befehl zu kompilieren ich nicht definiert Referenzfehler erhalten

[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 

Ist stimmt etwas mit der Template-Deklaration oder Implementierung nicht? Warum M Ich bekomme diese Verknüpfungsfehler:?

Antwort

88

Die Implementierung einer nicht spezialisierten Vorlage muss für eine Übersetzungseinheit sichtbar sein, die sie verwendet.

Der Compiler muss die Implementierung sehen können, um Code für alle Spezialisierungen in Ihrem Code zu generieren.

1) Bewegen Sie die Implementierung innerhalb der Kopfzeile:

Dies kann auf zwei Wegen erreicht werden.

2) Wenn Sie wollen, dass es getrennt zu halten, sie in einen anderen Kopf bewegen, die Sie in Ihrem ursprünglichen Header enthalten:

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

Viele Leute verwenden die Erweiterung '.tcc' für die Vorlagenimplementierung fi les. –

19

Sie haben 2 Möglichkeiten:

  1. Gerät convert2QString in util.h.

  2. manuell convert2QString mit int in util.cpp instanziieren und diese Spezialisierung als extern Funktion 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); 
} 
definieren