Specification d'une methode template et import depuis une librairie statique

[Résolu]
Signaler
Messages postés
15
Date d'inscription
lundi 11 octobre 2004
Statut
Membre
Dernière intervention
23 juin 2009
-
Messages postés
15
Date d'inscription
lundi 11 octobre 2004
Statut
Membre
Dernière intervention
23 juin 2009
-
Bonsoir... Je suis entrain de faire plusieurs petits programmes qui utilisent les mêmes classes et fonctions, j'ai des bibliotheques statiques (au moins 2) dont une principale qui est elle meme "appelée" par certaines autres bibliothèques statiques (secondaires) ainsi que par les programmes. Dans la bibliothèque principale j'ai une classe avec une fonction template et des specifications pour certains types. Le problème est que si je mets directement la specification dans le .h de ma classe je peux compiler mon autre bibliotheque statique (la secondaire) mais pas mon programme car il me dit que les specifications de la fonction template sont deja définis dans la bibliotheque secondaire, si je mets les specifications dans un fichier .cpp a part la bibliothèque secondaire et le programme compile mais ils n'utilisent pas les specifications... Pour etre plus clair je vais faire un petit schema :s

// Header et source de la premiere lib.
// Lib_principale.h
class maClass {
public :
template<class _Type> _Type uneMethode(_Type pValue) {
// Je fais qque chose.
return pValue;
}
};

// Lib_principale.cpp
#include <Lib_principale.h>
template<> char maClass::uneMethode(char pValue) {
// template<> char maClass::uneMethode<char>(char pValue) {
// Je fais autre chose.
return pValue;
}

// header et source de la 2eme lib.
// Lib_secondaire.h
#include <Lib_principale.h>

void uneFonction();

// Lib_secondaire.cpp
#include <Lib_secondaire.h>

void uneFonction() {
maClass xValue;

char c = xValue.uneMethode<char>('c');
int i = xValue.uneMethode(10);
}

// Programme qui utilise les deux lib.
#include <Lib_principale.h>
#include <Lib_secondaire.h>
uneFonction();

J'utilise GNU GCC avec codeblocks sous windows vista. J'ai evidement verifie que j'importais bien les deux librairies dans mon programme et la principale dans la deuxieme lib (d'ailleurs j'ai meme esseye sans au cas ou).

Merci d'avance a ceux qui ont déjà lu le message d'un bout à l'autre...

5 réponses

Messages postés
966
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
4 mars 2010
4
Je ne vois pas a priori de solution directe.
Peut-être cela pourrait-il fonctionner :

// lib_main.h
char _uneMethode_imp(char pValue);
__forceinline template<> char uneMethode(char pValue){return _uneMethode_imp(pValue);};

// lib_main.cpp
char _uneMethode_imp(char pValue)
{
...
}

Je ne sais pas quel est l'équivalent de __forceinline sous CB, peut-être simplement _inline. En tous cas, le principe est d'éviter la duplication des signatures des fonctions (ce qui empêche la compilation) en les passant en inline, en l'occurence juste un appel vers une fonction effectuant le travail prévu.
Messages postés
28
Date d'inscription
samedi 11 juin 2005
Statut
Membre
Dernière intervention
20 janvier 2009

Bonjour,
La description de ta fonction template ne peut se faire autre part que dans ton fichier d’entête d’après se que j’ai crue comprendre sur les templates.
Et sinon pour ton problème de double définition cela et du au fait que ton fichier d’entête principale et incluse 2 fois. Pour eviter sur problème il y a une façon assez simple qui et de faire comme dans les librairies standard :
<hr size="2" width="100%" />#ifndef TON_FICHIER_H
#define TON_FICHIER_H

// ici se trouve les déclarations

#endif
<hr size="2" width="100%" />
Messages postés
15
Date d'inscription
lundi 11 octobre 2004
Statut
Membre
Dernière intervention
23 juin 2009

Tout d'abord merci pour vos reponses.

[auteur/LGLANDEUR/531689.aspx lglandeur] : Je suis tout a fait d'accord avec toi sur tous les points que tu as mis. D'ailleurs pour l'histoire de mettre des #ifndef ....... ils y sont dans mon code, c'est juste qu'en simplifiant pour l'exemple j'ai légèrement trop simplifié :)

[auteur/JUJU12/255361.aspx juju12] : sous GCC le mot clef inline ou __inline__ suffisent mais ca me plait pas à 100%, le soucis est que si ma fonction est énorme, est se que en effet il va la reecrire systematiquement a chaque appel (du vrai inline quoi) ou au contraire il la créera une fois et fera un appel de fonction ordinaire... Parceque dans le premier cas mon prog peut vite grimper en taille. Donc je m'en mefie mais en effet ca marche comme ca !

En tout cas je continue a chercher, j'ai lu pas mal de message sur les templates et les problemes d'ecritures des specification (ou specialisation ???) j'ai vu des articles qui traitaient du mot clef 'extern' (c'est bon je crois avoir la solution :D !!!)  mais en me renseignant plus je suis tombé la dessus
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1426.pdf ca parle de pourquoi il faut pas utiliser le mot clef extern pour les exports de templates. fausse joie au final !
Messages postés
966
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
4 mars 2010
4
Ben effectivement en inline forcé il recopie tout le code à chaque fois...mais en l'occurence, le code recopié, c'est simplement un appel à la fonction où tu mets effectivement le traitement désiré, s'il est conséquent en taille : c'est à ça que servirait la fonction _uneMethode_imp() dans l'exemple.
Messages postés
15
Date d'inscription
lundi 11 octobre 2004
Statut
Membre
Dernière intervention
23 juin 2009

Olala escuse moi parceque je crois que j'ai regardé ton message trop vite et j'ai repondu aux messages trop lontemps après les avoir lu :) J'avais pas vu ca comme ca et en effet ta méthode est pas mal du tout au final... Je vais mettre que tu as répondu au problème ;) Merci encore en tout cas, des fois on cherche compliqué alors qu'on peut faire simple !

En fait j'ai pas mal cherché sur le mot export dans le document dont j'ai donné le lien (qui date de 2003) ils en disaient beaucoup de mal mais au final c'est le seul document que j'ai trouvé qui parlait de ça donc j'ai fini par utilisé une solution avec export qui t'oblige à faire un truc du genre dans mon fichier de déclaration (je le mets au cas où certains chercheraient)

#ifdefine _IMPLEMENTE_SPECIFICATION_TEMPLATE_
// Le mot clé _IMPLEMENTE_SPECIFICATION_TEMPLATE_ est défini dans mon EXE ou ma DLL.
template<> char maFonction<char>(char pValue) {
// Je fais qque chose.
return pValue;
}
#else
// La c'est pour les autres bibliothèques statiques.
template<> extern char maFonction<char>(char pValue);
#endif