OVH Cloud OVH Cloud

methode template dans une classe template

3 réponses
Avatar
franco bevilacqua
Bonjour tous,
J'aimerai specialiser l'operator() de la "classe" id2string pour qu'il
retourne soit une string soit une QString (string Qt).
Sachant que la classe id2string est deja parametre par un type de map.
Comment puis je faire ??

J'ai pensé à la chose suivante, mais ce n'est pas tres concluant:erreur
de compile ...

Avez vous une idée ???
Merci
@+

template<typename lexiconmap >
struct id2string
{
id2string(lexiconmap aLexmap):lexmap(aLexmap)
{

}
template<typename returntype>
returntype operator()(typename lexiconmap::key_type key ) const;
string operator()(typename lexiconmap::key_type key ) const
{
string ret("");
typename lexiconmap::const_iterator it(lexmap.find(key)) ;

if( it!= lexmap.end() )
{
ret=(*it).second.first;
}
return ret;
}
QString operator()(typename lexiconmap::key_type key ) const
{
QString ret("");
typename lexiconmap::const_iterator it(lexmap.find(key)) ;

if( it!= lexmap.end() )
{
ret=(*it).second.second;
}
return ret;
}
private:
lexiconmap lexmap;
};

3 réponses

Avatar
Jean-Marc Bourguet
franco bevilacqua writes:

Bonjour tous,
J'aimerai specialiser l'operator() de la "classe" id2string pour qu'il
retourne soit une string soit une QString (string Qt).
Sachant que la classe id2string est deja parametre par un type de map.
Comment puis je faire ??

J'ai pensé à la chose suivante, mais ce n'est pas tres concluant:erreur de
compile ...

Avez vous une idée ???


Si j'ai bonne memoire, je vois deux problemes:

1/ il n'y pas possible d'instancier explicitement dans une classe.
-> il faudrait sortir les instanciations explicites de la declaration
de id2string.

2/ il n'est pas possible d'instancier explicitement un template inclus
dans un template non instancie explicitement.

Puisque ce que tu as l'air de vouloir c'est de la surcharge sur le
type de retour,
- puisque tu es pret a nommer differemment tes appels, pourquoi ne
pas utiliser des noms plus explicites que operator() et donc
eviter le besoin de surcharge?

- puisque tu es pret a nommer differemment tes appels, un work
around est de faire de la surcharge sur un parametre.

struct as_string_t {} as_string;
struct as_qstring_t {} as_qstring;

std::string operator(as_string_t) {...}
QString operator(as_qstring_t) {...}

- si tu veux eviter de differentier les appels, le moyen habituel
est de retourner un proxy qui se converti implicitement dans les
types desires. Ce sont les operateurs de conversion du proxy qui
font le boulot.

(c'est dans mon ordre de preference, il me faudrait de reellement
bonnes raisons d'avoir de la surcharge pour utiliser la troisieme
professionnellement)

A+

--
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++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Eric Pruneau
"franco bevilacqua" a écrit dans
le message de news: dlhoj0$4rv$
Bonjour tous,
J'aimerai specialiser l'operator() de la "classe" id2string pour qu'il
retourne soit une string soit une QString (string Qt).
Sachant que la classe id2string est deja parametre par un type de map.
Comment puis je faire ??

J'ai pensé à la chose suivante, mais ce n'est pas tres concluant:erreur de
compile ...

Avez vous une idée ???
Merci
@+



Je vois 2 moyens, un simple et un autre un peu plus compliqué.

1. faire un overload de l'opérateur().

Ok tu ne peux pas faire d'overload sur le type de retour. Il faut alors
ajouter un parametre. Une façon élégante est d'utiliser Type2Type de Loki.
http://sourceforge.net/projects/loki-lib/


Voici le code que tu as de besoin si tu ne veux pas installer Loki

template <typename T>
struct Type2Type
{
typedef T OriginalType;
Type2Type(){} // pour VC7
};

Un peu de doc sur Type2Type
http://aszt.inf.elte.hu/~gsd/halado_cpp/ch06s09.html


string operator()(typename lexiconmap::key_type key, Type2Type<string> )
const { ... }

QString operator()(typename lexiconmap::key_type key, Type2Type<QString> )
const { ... }

tu fait l'appel des ces fonctions comme ca

string str = id2string(key, Type2Type<string>);
QString qstr = id2string(key, Type2Type<QString>);

***

2. utiliser boost::enable_if_c. Cependant je te recommande la précédente...
http://www.boost.org/libs/utility/enable_if.html

OK probablement que tu ne veux pas télécharger et intaller boost simplement
pour
utiliser cette fonctionnalité... Alors voici le code qu'il te faut. (en
passant certain compilateur
ne peuvent pas compiler ce code alors dans ce cas, il y a peut etre un autre
moyen de
faire la même chose, mais je ne sais pas comment)

template <bool B, class T = void>
struct enable_if_c {
typedef T type;
};

template <class T>
struct enable_if_c<false, T> {};

---
tu peux alors écrire:

typename enable_if< critere1, string>:: type
operator()(typename lexiconmap::key_type key ) const { ... }

et

typename enable_if< critere2, QString>:: type
operator()(typename lexiconmap::key_type key ) const { ... }

---

Il te rete a définir critère1 et critere2 qui doivent être un BOOL
évalué au moment de la compilation. Ceci est probablement moins
évident...


Eric

Avatar
Eric Pruneau
"Eric Pruneau" a écrit dans le message de news:
L83ff.46900$

"franco bevilacqua" a écrit
dans le message de news: dlhoj0$4rv$
Bonjour tous,
J'aimerai specialiser l'operator() de la "classe" id2string pour qu'il
retourne soit une string soit une QString (string Qt).
Sachant que la classe id2string est deja parametre par un type de map.
Comment puis je faire ??

J'ai pensé à la chose suivante, mais ce n'est pas tres concluant:erreur
de compile ...

Avez vous une idée ???
Merci
@+



Je vois 2 moyens, un simple et un autre un peu plus compliqué.

1. faire un overload de l'opérateur().

Ok tu ne peux pas faire d'overload sur le type de retour. Il faut alors
ajouter un parametre. Une façon élégante est d'utiliser Type2Type de Loki.
http://sourceforge.net/projects/loki-lib/


Voici le code que tu as de besoin si tu ne veux pas installer Loki

template <typename T>
struct Type2Type
{
typedef T OriginalType;
Type2Type(){} // pour VC7
};

Un peu de doc sur Type2Type
http://aszt.inf.elte.hu/~gsd/halado_cpp/ch06s09.html


string operator()(typename lexiconmap::key_type key, Type2Type<string> )
const { ... }

QString operator()(typename lexiconmap::key_type key,
ype2Type<QString> ) const { ... }

tu fait l'appel des ces fonctions comme ca

string str = id2string(key, Type2Type<string>);
QString qstr = id2string(key, Type2Type<QString>);

***

2. utiliser boost::enable_if_c. Cependant je te recommande la
précédente...
http://www.boost.org/libs/utility/enable_if.html

OK probablement que tu ne veux pas télécharger et intaller boost
simplement pour
utiliser cette fonctionnalité... Alors voici le code qu'il te faut. (en
passant certain compilateur
ne peuvent pas compiler ce code alors dans ce cas, il y a peut etre un
autre moyen de
faire la même chose, mais je ne sais pas comment)

template <bool B, class T = void>
struct enable_if_c {
typedef T type;
};

template <class T>
struct enable_if_c<false, T> {};

---
tu peux alors écrire:

typename enable_if< critere1, string>:: type
operator()(typename lexiconmap::key_type key ) const { ... }

et

typename enable_if< critere2, QString>:: type
operator()(typename lexiconmap::key_type key ) const { ... }

---

Il te rete a définir critère1 et critere2 qui doivent être un BOOL
évalué au moment de la compilation. Ceci est probablement moins
évident...


Eric


crtere1 peut etre:
Loki::IsSameType<lexiconmap, strig>::value

et critere 2
Loki::IsSameType<lexiconmap, QStrig>::value