J'ai trois fichiers. Le contenu de main.cpp est
#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);
}
}
Lorsque j'essaie de compiler ces fichiers avec la commande suivante, j'obtiens une erreur de référence non définie.
vickey@tb:~/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
Y at-il quelque chose qui ne va pas avec la déclaration de modèle ou la mise en œuvre? Pourquoi M je obtenir ces erreurs de liaison:?
L'implémentation d'un modèle non spécialisé doit être visible pour une unité de traduction qui l'utilise.
Le compilateur doit pouvoir voir l'implémentation afin de générer du code pour toutes les spécialisations de votre code.
Ceci peut être réalisé de deux manières:
1) Déplacez l'implémentation dans l'en-tête.
2) Si vous souhaitez le garder séparé, déplacez-le dans un en-tête différent que vous incluez dans votre en-tête d'origine:
til.h
namespace Util
{
template<class T>
QString convert2QString(T type , int digits=0);
}
#include "util_impl.h"
til_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);
}
}
Vous avez 2 façons:
Mettre en place convert2QString
in util.h.
Instancier manuellement convert2QString
avec int
dans util.cpp et définir cette spécialisation en tant que fonction externe dans 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);
}