Déclaration explicite de template
Le
Mickaël Wolff
Bonjour la liste,
J'espère que vous passez (ou avez passé) de bonnes vacances.
En ces temps estivaux, j'ai écrit une application dans laquelle j'ai
définit des templates. L'un d'entre eux est :
// Fichier <engine.h>
template<typename StrNeedle, typename StrHaystack = StrNeedle>
class search_engine ;
La définition étant un peu plus loin.
Une partie des fonction est définie dans un fichier <engine-impl.h>,
qui est un fichier contenant les définition des plus grosses fonctions
que je ne souhaite pas rendre inline. Donc j'ai un fichier <engine.cpp>
dans lequel je force l'« instantiation » des templates :
#include "engine-impl.h"
template class search_engine <std::wstring> ;
Vu que les fonctions correspondant à ces instantiations de template
sont déjà disponible, j'aimerais le signaler dans le fichier d'en-tête
<engine.h>. C'est surtout pour prévenir les problèmes d'édition de lien
liés à une déclaration multiples des fonctions. Pour ce faire, j'ai
rajouté :
class search_engine <std::wstring> ;
Mais contrairement aux classes normales, cela entraîne des erreurs
sur l'instantiation explicite de mes template.
Y a-t-il une méthode plus propre permettant de prévenir que certains
templates sont instanciés ? (j'ai essayé avec typedef et extern, mais
rien n'y fait).
Je compile avec g++ 4.3.1 sous Debian GNU/Linux. L'erreur suivante
survient lorsque je tente de déclarer un template instancié :
explicit instantiation of ‘struct
warg::search_engine<std::basic_string<wchar_t, std::char_
traits<wchar_t>, std::allocator<wchar_t> >, std::basic_string<wchar_t,
std::char_traits<wchar_t>, std::allocator<wc
har_t> > >’ before definition of template
Merci :)
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
J'espère que vous passez (ou avez passé) de bonnes vacances.
En ces temps estivaux, j'ai écrit une application dans laquelle j'ai
définit des templates. L'un d'entre eux est :
// Fichier <engine.h>
template<typename StrNeedle, typename StrHaystack = StrNeedle>
class search_engine ;
La définition étant un peu plus loin.
Une partie des fonction est définie dans un fichier <engine-impl.h>,
qui est un fichier contenant les définition des plus grosses fonctions
que je ne souhaite pas rendre inline. Donc j'ai un fichier <engine.cpp>
dans lequel je force l'« instantiation » des templates :
#include "engine-impl.h"
template class search_engine <std::wstring> ;
Vu que les fonctions correspondant à ces instantiations de template
sont déjà disponible, j'aimerais le signaler dans le fichier d'en-tête
<engine.h>. C'est surtout pour prévenir les problèmes d'édition de lien
liés à une déclaration multiples des fonctions. Pour ce faire, j'ai
rajouté :
class search_engine <std::wstring> ;
Mais contrairement aux classes normales, cela entraîne des erreurs
sur l'instantiation explicite de mes template.
Y a-t-il une méthode plus propre permettant de prévenir que certains
templates sont instanciés ? (j'ai essayé avec typedef et extern, mais
rien n'y fait).
Je compile avec g++ 4.3.1 sous Debian GNU/Linux. L'erreur suivante
survient lorsque je tente de déclarer un template instancié :
explicit instantiation of ‘struct
warg::search_engine<std::basic_string<wchar_t, std::char_
traits<wchar_t>, std::allocator<wchar_t> >, std::basic_string<wchar_t,
std::char_traits<wchar_t>, std::allocator<wc
har_t> > >’ before definition of template
Merci :)
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org

Poser une question


J'ai peur de ne pas tout suivre. Quels problèmes as-tu exactement ?
Peux-tu donner un code minimal (mais complet) qui illustre le
problème ?
Je ne saisis pas bien ce que tu veux faire, mais j'ai l'impression que
tu mélanges l'instanciation d'une classe template, et instanciation de
ses fonctions membres.
Prends l'exemple du code suivant :
#include <string>
template <class T> class C
{
public: void f() { T::foo(); }
};
class HasFoo
{
public: static void foo() {}
};
int main()
{
C <HasFoo> c_foo; // 1
c_foo.f(); // 2
C <std::string> c_string; // 3
// c_string.f(); // 4
}
En (1), la classe C En (2), la fonction C En (3), la classe C
En (4), la fonction C<std::string>::f() ne peut pas être instanciée,
car std::string::foo() n'existe pas. (J'ai mis le code en commentaire
car il est erronné.)
Je ne peux pas spécifier dans un en-tête qu'une instantiation de
template existe déjà.
D'après mes essais, l'instantiation explicite de la template
instancie les fonctions membre de la classe template.
[snip]
Effectivement, ça j'ai bien compris. C'est le principe de base de la
STL. J'ai écrit un petit exemple, que je mets en fin de message. Je fais
juste une parenthèse pour dire que ce que je présente ici fonctionne
très bien. Mon seul soucis, c'est que dans le fichier d'en-tête (tpl.h
dans l'exemple, et non tpl-impl.h), les templates instanciés ne sont pas
déclarés, et qu'il m'est impossible de faire un typedef sans avoir
d'erreurs.
==
int main(int argc, char ** argv)
{
// pas d'instantiation, puisque déjà instancié
engine<std;;string> e("The street") ;
e.walk() ;
}
==
// On force l'instanciation du template en utilisant
// l'instanciation explicite :
template class engine<std::string> ;
==
template <typename T>
engine::engine()
{
}
template <typename T>
void engine::walk()
{
}
== class engine
{
public:
engine() ;
void walk() ;
} /* class engine */ ;
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
extern template devrait resoudre ton probleme dans C++0X, si je l'ai bien
compris.
http://www.open-std.org/jtc1/sc22/w.../n1987.htm
Il me semble me souvenir que gcc fournit cela comme extension depuis
longtemps, mais j'ai pas le temps de regarder.
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++...index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Je ne suis pas sûr ce que dit la norme à cet égard ; je crois
rien. Mais dans la practique, si la définition d'un tempate dont
le compilateur a besoin n'est pas disponible lors de la
compilation, le compilateur « suppose » qu'il a été instantié
ailleur.
--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34