C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Utilisation de spécialisation de template pour convertir.
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Stephane Wirtel
Guest





PostPosted: Mon Apr 18, 2005 5:57 pm    Post subject: Utilisation de spécialisation de template pour convertir. Reply with quote



Bonjour,

Est-il possible de créer un template via spécialisation permettant
de convertir des types définit (bool, int, string, ...) vers un
std::string ?

Je m'explique.

J'essaie de créer une classe permettant de lire des settings provenant d'un
fichier de conf.

Donc, dedans, j'ai créé une méthode générique, du style :

class Settings {
private:
typedef std::map <std::string, std::string> MapSettings;
MapSettings mSettings;
public:
template <class T> const T& Read (const std::string& pVariable,
const T& pDefaultValue) {
/**
* Si variable présente dans la map on retourne la valeur
* trouvée, sinon, on retourne la valeur par défaut.
* On rajoute tout de même pDefaultValue dans map pour une prochaine
* utilisation.
*/

mSettings[pVariable] = TranslateToString (pDefaultValue);

return pDefaultValue;
}
};

Ce que j'aimerais c'est que TranslateToString prenne ma valeur et la
transforme directement en chaine de caractère.
Pour cela, j'avais pensé à un template sur une fonction ou sur une méthode,
mais cela ne semble pas fonctionner correctement. Voir mon post précédent.

Mais sinon, j'avais pensé à ceci.

dans ma classe Settings, il y aurait la méthode TranslateToString définie
comme suit :
class Settings {
private:
...
public:
...
template <class T> std::string TranslateToString (const T& pValue) {
}
template <> std::string TranslateToString <bool> (const bool& pValue) {
return (pValue ? "True" : "False");
}
template <> std::string TranslateToString <int> (const int& pValue) {
return "Chaine de test...";
}
};

Est-ce que quelqu'un peut m'aider ? Il me manque une solution pour résoudre
mon problème qui je pense doit certainement avec une réponse de ce type.

Merci d'avance,


Stéphane
--
Stephane Wirtel <stephane.wirtel (AT) belgacom (DOT) net>
Back to top
Vincent Lascaux
Guest





PostPosted: Mon Apr 18, 2005 6:14 pm    Post subject: Re: Utilisation de spécialisation de template pour convertir Reply with quote




"Stephane Wirtel" <stephane.wirtel (AT) belgacom (DOT) net> a écrit dans le message de
news: d40sf1$bjf$1 (AT) news (DOT) brutele.be...
Quote:
Bonjour,

Est-il possible de créer un template via spécialisation permettant
de convertir des types définit (bool, int, string, ...) vers un
std::string ?

Tu peux aller voir boost::lexical_cast
Ta fonction TranslateToString peut être implémentée comme ca (et c'est ce
que fait boost à peu de chose près)

template<class T>
std::string TranslateToString(const T& value)
{
std::stringstream s;
s << value;
return s.str();
}

Pour que ca marche, il faut qu'il y ait un opérateur ostream << T (il y a ca
pour tous les types de bases, et tu devras le définir si tu veux traduire
des classes à toi)

--
Vincent



Back to top
Stephane Wirtel
Guest





PostPosted: Mon Apr 18, 2005 6:47 pm    Post subject: Re: Utilisation de spécialisation de template pour convertir Reply with quote




Quote:
template<class T
std::string TranslateToString(const T& value)
{
std::stringstream s;
s << value;
return s.str();
}

Pour que ca marche, il faut qu'il y ait un opérateur ostream << T (il y a
ca pour tous les types de bases, et tu devras le définir si tu veux
traduire des classes à toi)

Merci vincent,

Actuelle, cela se limite uniquement à des types primitifs, int, char*
(string) et bool, et certainement double.

Quote:


--
Stephane Wirtel
Back to top
Christophe de Vienne
Guest





PostPosted: Tue Apr 19, 2005 7:48 am    Post subject: Re: Utilisation de spécialisation de template pour convertir Reply with quote

Stephane Wirtel wrote:

Quote:
Bonjour,

Est-il possible de créer un template via spécialisation permettant
de convertir des types définit (bool, int, string, ...) vers un
std::string ?

Je m'explique.

J'essaie de créer une classe permettant de lire des settings provenant
d'un fichier de conf.

Donc, dedans, j'ai créé une méthode générique, du style :

class Settings {
private:
typedef std::map <std::string, std::string> MapSettings;
MapSettings mSettings;
public:
template <class T> const T& Read (const std::string& pVariable,
const T& pDefaultValue) {
/**
* Si variable présente dans la map on retourne la valeur
* trouvée, sinon, on retourne la valeur par défaut.
* On rajoute tout de même pDefaultValue dans map pour une
prochaine * utilisation.
*/

mSettings[pVariable] = TranslateToString (pDefaultValue);

return pDefaultValue;
}
};

Ce que j'aimerais c'est que TranslateToString prenne ma valeur et la
transforme directement en chaine de caractère.
Pour cela, j'avais pensé à un template sur une fonction ou sur une
méthode, mais cela ne semble pas fonctionner correctement.

Peux-tu être plus précis pour le cas présent : qu'est-ce qui ne fonctionne
pas ?

Quote:
Voir mon post
précédent.

Mais sinon, j'avais pensé à ceci.

dans ma classe Settings, il y aurait la méthode TranslateToString définie
comme suit :
class Settings {
private:
...
public:
...
template <class T> std::string TranslateToString (const T& pValue)
{ }
template <> std::string TranslateToString <bool> (const bool&
pValue) {
return (pValue ? "True" : "False");
}
template <> std::string TranslateToString <int> (const int&
pValue) {
return "Chaine de test...";
}
};

Pouquoi passer par des templates alors que la surchage fonctionne ?

std::string TranslateToString(std::string const & value) { return value; }
std::string TranslateToString(bool value) { return value ? "True" :
"False"; }

etc...

A la limite, j'utiliserais template pour faire une implémentation par
défaut :

template<typename T> std::string TranslateToString(T const & value) {
std::stringstream o;
o << value;
return o.str();
}



A+

Christophe


Back to top
Stephane Wirtel
Guest





PostPosted: Tue Apr 19, 2005 8:21 am    Post subject: Re: Utilisation de spécialisation de template pour convertir Reply with quote

Quote:
template<typename T> std::string TranslateToString(T const & value) {
std::stringstream o;
o << value;
return o.str();
}
Effectivement, c'est ce que Vincent m'avait proposé hier soir, et que j'ai appliqué.

Le tout fonctionne nickel.

Pour quelle raison les templates ?
1) J'essaie d'apprendre les templates, et de les maitriser.
2) Voir leurs possibilités.
3) Pas envie de faire plusieurs copier/coller de la même fonction.

Mais merci de tes propositions,

Stéphane

Back to top
Stephane Wirtel
Guest





PostPosted: Tue Apr 19, 2005 8:43 am    Post subject: Re: Utilisation de spécialisation de template pour convertir Reply with quote

Dans la même idée, après le TranslateToString,

le StringTo.

Voici ce que j'essaie :

template <class T> const T& StringTo (const std::string& pValue) {
std::istringstream iss (pValue, std::istringstream::in);
T data;
iss >> data;
return data;
}


Je me suis basé sur l'exemple donné :
http://www.cplusplus.com/ref/iostream/istringstream/istringstream.html

Et voici la fameuse méthode qui appel StringTo

class DsSettings : public DsSingleton <DsSettings> {
private:
...
typedef std::map <std::string, std::string> MapSettings;
MapSettings mSettings;
...
public:
template <class T> const T& Read (const std::string& pVariable, const T& pDefaultValue) {
if (!VariableIsPresent (pVariable)) {
mSettings[pVariable] = TranslateToString (pDefaultValue);
mIsModified = true;
return pDefaultValue;
} else {
return StringTo (mSettings[pVariable]);
}
}
};

DsSettings::Read est utilisée de la manière suivante :

DsSettings& mSettings = DsSettings::GetInstance();
int smtpPort = mSettings.Read ("Port", 25);
int hostname = mSettings.Read ("Hostname", "localhost");

Donc, tout comme la fonction TranslateToString qui me permettait de transformer le type des valeurs vers des std::string,
j'aimerais savoir si il est possible de transformer mes std::string vers les types employés lors de l'appel de ma méthode template ?


Merci d'avance,

Stéphane
Back to top
Samuel Krempp
Guest





PostPosted: Tue Apr 19, 2005 9:41 am    Post subject: Re: Utilisation de spécialisation de template pour convertir Reply with quote

le Tuesday 19 April 2005 10:43, [email]stephane.wirtel (AT) descasoft (DOT) com[/email] écrivit :

Quote:
DsSettings::Read est utilisée de la manière suivante :

DsSettings& mSettings = DsSettings::GetInstance();
int smtpPort = mSettings.Read ("Port", 25);
int hostname = mSettings.Read ("Hostname", "localhost");

Donc, tout comme la fonction TranslateToString qui me permettait de
transformer le type des valeurs vers des std::string, j'aimerais savoir si
il est possible de transformer mes std::string vers les types employés
lors de l'appel de ma méthode template ?

euh, mais c'est ce que fait la fonction stringTo, où est le problème ?

Juste un détail à propos du code ici :
Quote:
string hostname = mSettings.Read ("Hostname", "localhost");
(je suppose que c'est string hostname, pas int hostname comme dans le

message..)

utiliser la valeur par défaut pour en déduire le type voulu marche dans le
cas général, mais là le type ne sera pas string (plutot const char[9], ou
char * ..).
il faudrait expliciter le parametre template :

string hostname = mSettings.Read<string> ("Hostname", "localhost");

(et en passant, on pourrait spécialiser stringTo pour T=string :
template <> const std::string&
StringTo<std::string> (const std::string& pValue) {
return pValue;
}

ça éviterait de construire un stringstream inutilement pour lire un
string ...

c'est le genre de détails que boost::lexical_cast gère probablement
directement)


--
Sam

Back to top
Stephane Wirtel
Guest





PostPosted: Tue Apr 19, 2005 12:14 pm    Post subject: Re: Utilisation de spécialisation de template pour convertir Reply with quote

Quote:
Donc, tout comme la fonction TranslateToString qui me permettait de
transformer le type des valeurs vers des std::string, j'aimerais savoir
si il est possible de transformer mes std::string vers les types employés
lors de l'appel de ma méthode template ?

euh, mais c'est ce que fait la fonction stringTo, où est le problème ?
Le voici le problème :

DsSettings.hpp: In member function `const T& DsSante::DsSettings::Read(const
std::string&, const T&) [with T = char[5]]':
DsSante.cpp:22: instantiated from here
DsSettings.hpp:51: error: no matching function for call to `StringTo(
std::basic_string<char, std::char_traits&)'
DsSettings.hpp: In member function `const T& DsSante::DsSettings::Read(const
std::string&, const T&) [with T = char[6]]':
DsSante.cpp:23: instantiated from here
DsSettings.hpp:51: error: no matching function for call to `StringTo(
std::basic_string<char, std::char_traits&)'
DsSettings.hpp: In member function `const T& DsSante::DsSettings::Read(const
std::string&, const T&) [with T = int]':
DsSante.cpp:25: instantiated from here
DsSettings.hpp:51: error: no matching function for call to `StringTo(
std::basic_string<char, std::char_traits&)'
make: *** [DsSante.o] Error 1



Quote:

Juste un détail à propos du code ici :
string hostname = mSettings.Read ("Hostname", "localhost");
(je suppose que c'est string hostname, pas int hostname comme dans le
message..)
Effectivement, il s'agit bien de string hostname, j'ai fais une ptite

boulette ;-)

Quote:

utiliser la valeur par défaut pour en déduire le type voulu marche dans le
cas général, mais là le type ne sera pas string (plutot const char[9], ou
char * ..).
il faudrait expliciter le parametre template :

string hostname = mSettings.Read<string> ("Hostname", "localhost");
Je ne veux utiliser un template de manière explicite, j'aimerais que cela

soit implicite, ce qui me permettra de créer du code bien plus dynamique.

Quote:
(et en passant, on pourrait spécialiser stringTo pour T=string :
template <> const std::string&
StringTo<std::string> (const std::string& pValue) {
return pValue;
}

ça éviterait de construire un stringstream inutilement pour lire un
string ...
Je suis tout à fait d'accord avec toi.


Quote:

c'est le genre de détails que boost::lexical_cast gère probablement
directement)
J'essaie de faire cela sans boost, afin d'apprendre.


Le but de tout cela, est de simplement stocké les valeurs lûe depuis un
fichier XML, ou plat et de les stocker dans une map, vu que ne je ne peux
pas faire de template sur une map Wink je passe directement par des strings,

d'ou mon typedef std::map <std::string, std::string> MapSettings;

Donc, en gros, tout nouveau paramètre, je le transforme en string pour
l'introduire dans la map, et quand je désire récupérer sa valeur,
j'aimerais que la chaine de caractère se transforme dans le type de retour.



Back to top
Samuel Krempp
Guest





PostPosted: Tue Apr 19, 2005 1:20 pm    Post subject: Re: Utilisation de spécialisation de template pour convertir Reply with quote

le Tuesday 19 April 2005 14:14, [email]stephane.wirtel (AT) belgacom (DOT) net[/email] écrivit :

Quote:
DsSettings.hpp: In member function `const T&
DsSante::DsSettings::Read(const
std::string&, const T&) [with T = int]':
DsSante.cpp:25: instantiated from here
DsSettings.hpp:51: error: no matching function for call to `StringTo(
std::basic_string<char, std::char_traits &)'

ah oui j'avais pas pensé à ça, pour stringTo le type T ne peut être déduit,
puisque le paramètre de la fonction ne dépend pas de T..

il faut modifier Read :
return StringTo
Quote:
string hostname = mSettings.Read<string> ("Hostname", "localhost");
Je ne veux utiliser un template de manière explicite, j'aimerais que cela
soit implicite, ce qui me permettra de créer du code bien plus dynamique.

euh, bon, mais parfois il n'y a pas vraiment le choix.
Ici, "localhost" sera de type char[9], donc la déduction de T à partir du
paramètre ne donnera rien de bon.
solutions :
1. expliciter le parametre template comme je disais (ça ne diminue pas la
généricité du code à mon avis..)
2. string hostname = mSettings.Read("Hostname", string("localhost"));
-> impose de taper plus
3. spécialiser Read pour T=const char* pour éviter le problème
-> duplique inutilement du code. enfin, du coup on peut carrément éviter
l'appel à stringTo dans ce Read<const char*> spécialisé..

--
Sam

Back to top
Jean-Marc Bourguet
Guest





PostPosted: Tue Apr 19, 2005 1:50 pm    Post subject: Re: Utilisation de spécialisation de template pour convertir Reply with quote

Samuel Krempp <krempp (AT) crans (DOT) truc.en.trop.ens-cachan.fr> writes:

Quote:
3. spécialiser Read pour T=const char* pour éviter le problème
-> duplique inutilement du code. enfin, du coup on peut carrément éviter
l'appel à stringTo dans ce Read<const char*> spécialisé..

Qu'est-ce que ça change? La spécialisation sur char
const[9] sera meilleure et générée si besoin est. Une
surchage du genre

template <int N>
void Read(std::string const&, char const (&p) [N]);

devrait elle être préférée si j'ai bien compris (en tout
cas, ça passe avec como 4.3.3 et g++ 3.3.4).

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

Back to top
Samuel Krempp
Guest





PostPosted: Tue Apr 19, 2005 3:05 pm    Post subject: Re: Utilisation de spécialisation de template pour convertir Reply with quote

le Tuesday 19 April 2005 15:50, [email]jm (AT) bourguet (DOT) org[/email] écrivit :

Quote:
Samuel Krempp <krempp (AT) crans (DOT) truc.en.trop.ens-cachan.fr> writes:

3. spécialiser Read pour T=const char* pour éviter le problème
-> duplique inutilement du code. enfin, du coup on peut carrément éviter
l'appel à stringTo dans ce Read<const char*> spécialisé..

Qu'est-ce que ça change? La spécialisation sur char
const[9] sera meilleure et générée si besoin est. Une
surchage du genre
template <int N
void Read(std::string const&, char const (&p) [N]);


ah oui, je voulais juste dire qu'il ne fallait pas laisser le code générique
gèrer le cas char[N], mais effectivement il faudrait *surcharger* pour
char* (ou char[N] ..), et non pas *spécialiser* comme j'ai dit. j'ai
tendance à faire la confusion quand je vais trop vite, alors que surcharge
et spécialisation sont des mécanismes bien différents.

Bref, les surcharges
void Read(std::string const&, char const* );
ou
template void Read(std::string const&, char const (&p) [N]);

permettraient de faire ce qu'on veut.

--
Sam

Back to top
Pierre THIERRY
Guest





PostPosted: Sat May 07, 2005 8:19 pm    Post subject: Re: Utilisation de spécialisation de template pour convertir Reply with quote

Le Mon, 18 Apr 2005 19:57:57 +0200, Stephane Wirtel a écrit :
Quote:
template <class T> std::string TranslateToString (const T& pValue) {
}
template <> std::string TranslateToString <bool> (const bool& pValue) {
return (pValue ? "True" : "False");
}
template <> std::string TranslateToString <int> (const int& pValue) {
return "Chaine de test...";
}

Il semble que tu n'aies pas bien saisi la spécialistation de patrons de
fonctions... Ici ton patron ne contient aucun code, donc tu sembles
avoir besoin de surdéfinition, pas de patrons. De plus, on ne spécialise
pas un patron avec le mot clef template.

Le patron sert à appliquer un alogrithme strictement identique, au type
près, à des objets de types différents. Le compilateur créera des
instances du patron lorsqu'il en rencontrera le besoin. Exemple :

template<class T> T mediane(T a, T b, T c)
{
T temp1, temp2;
if (a <= b) {
temp1 = b; temp2 = a;
} else {
temp1 = a; temp2 = b;
}
if (temp1 > c) {
temp1 = c;
}
if (temp1 < temp2) {
temp1 = temp2;
}
return temp1;
}

Avec ça, si tu utilises, sans déclaration ou définition supplémentaire,
la fonction mediane sur n'importe quel type possédant les opérateurs '=',
'>', '<' et '<=', le compilateur générera une fonction appropriée.

Et si pour un type particulier, le traitement est différent, tu
spécialise :

TypeBizarre mediane(TypeBizarre a, TypeBizarre b, TypeBizarre c)
{
return a->fonction_bizarre(b, c);
}

Si l'algo est différent pour chacun des types dont tu vas te servir,
alors pas besoin de patrons. Tu écris la fonction normalement pour
chacun des types, c'est juste de la surdéfinition.

De plus, s'essayer aux particularités du C++ est louable, mais si tu
veux apprendre à manipuler toutes les possibilités du C++, fais-le dans
des conditions où c'est vraiment utile, ou tu risques d'associer
certaines solutions aux mauvais problèmes.

Prends un cours de C++ qui contient des exercices, c'est encore la voie
royale. Les deux bouquins de Delannoy sur le C++ sont très bien, par
exemple.

Pédagogiquement,
Nowhere man
--
[email]nowhere.man (AT) levallois (DOT) eu.org[/email]
OpenPGP 0xD9D50D8A


Back to top
Michel Michaud
Guest





PostPosted: Sun May 08, 2005 3:42 am    Post subject: Re: Utilisation de spécialisation de template pour convertir Reply with quote

Dans le message [email]pan.2005.05.07.20.19.20.330710 (AT) levallois (DOT) eu.org[/email],
Pierre THIERRY <nowhere.man (AT) levallois (DOT) eu.org> a écrit :
Quote:
Prends un cours de C++ qui contient des exercices, c'est encore la
voie royale. Les deux bouquins de Delannoy sur le C++ sont très
bien, par exemple.

Il les a récrits récemment ? Sinon « sont très bien » n'est pas le
commentaire qu'on a le plus souvent indiqué sur ce forum...

--
Michel Michaud [email]mm (AT) gdzid (DOT) com[/email]
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/


Back to top
Stephane Wirtel
Guest





PostPosted: Sun May 08, 2005 8:51 am    Post subject: Re: Utilisation de spécialisation de template pour convertir Reply with quote

J'ai ré-écrit complètement mes méthodes qui permettaient de convertir un
type vers un std::stringstream, que je reconverti vers un std::string.

Voici le code des méthodes.

template <class TypeData> std::string TranslateToString (TypeData pValue) {
std::stringstream inputStream;
inputStream << pValue;
return inputStream.str ();
}

template std::stringstream iss (pValue, std::istringstream::in);
TypeData data;
iss >> data;
return data;
}

L'utilité de ce code était de stocker la valeur d'une variable de type
différent vers un std::string dans une std::map. Et lors de la lecture de
la variable, une conversion était faite dans le type d'origine de la
variable.

Maintenant, je vais essayer d'employer boost::any ou de créer ma propre
classe pour stocker des variables de types différents dans une std::map.
Sans devoir faire la conversion en std::string, ce qui me donnera la
possiblité de ne pas perdre d'information lors d'une conversion
déffectueuse.
Back to top
Pierre THIERRY
Guest





PostPosted: Sun May 08, 2005 11:59 am    Post subject: Re: Re: Utilisation de spécialisation de template pour conve Reply with quote

Le Sat, 07 May 2005 23:42:07 -0400, Michel Michaud a écrit :
Quote:
Les deux bouquins de Delannoy sur le C++ sont très bien, par exemple.
Il les a récrits récemment ?

J'ai respectivement la 5ème édition mise à jour (2000) et la 2ème
édition mise à jour et augmentée (2001) du cours et des exercices.

Quote:
Sinon « sont très bien » n'est pas le commentaire qu'on a le plus
souvent indiqué sur ce forum...

Le cours s'adresse à quelqu'un qui connaît le C, et opère le passage C
vers C++. La progression pédagogique est bien pensée, et on produit tout
de suite du code fonctionnel sans se prendre la tête. Notamment, on voit
le strict nécessaire quant à l'utilisation de cout/cin dès le début,
pour s'en servir tout au long du bouquin, les flux n'étant réellement
abordés que beaucoup plus tard.

Quand, après n'avoir pas programmé pendant longtemps, je me suis remis
au C++, je n'ai eu aucun mal à m'y retrouver, le bouquin se resurvole
aisément, pour se rafraichir la mémoire.

Néanmoins, comme il fait le passage C vers C++, il n'est pas exhaustif,
et n'est donc pas forcément le meilleur choix comme référence à garder
sous la main.

N'en ayant pas lu d'autre, je ne peux pas comparer...

Philologiquement,
Nowhere man
--
[email]nowhere.man (AT) levallois (DOT) eu.org[/email]
OpenPGP 0xD9D50D8A


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.