 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
MGN Guest
|
Posted: Fri Oct 13, 2006 1:13 am Post subject: pb de conversion en std::string |
|
|
mon problème est simple.
J'ai un modèle de classe
template<class T>
modele
{
// blablabla...
std::string display(void) const;
};
et dedans j'ai une méthode display qui fournit des renseignements sur le
contenu de modele (je simplifie pour aller à l'essentiel)
Ma question : y-a-t-il un moyen de savoir si l'opérateur de conversion
(std::string) est défini pour les objets de la classe T ?
Actuellement, la conversion est tentée à la compilation et modele<T> n'est
pas compilé si cette conversion n'est pas possible.
Je voudrais que la conversion soit testée à l'exécution...
Est-ce que c'est possible ?
J'espère avoir été clair ... |
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Fri Oct 13, 2006 4:21 am Post subject: Re: pb de conversion en std::string |
|
|
On Thu, 12 Oct 2006 22:13:30 +0200, "MGN" <mgueguen (AT) metrica (DOT) fr>:
| Quote: | Ma question : y-a-t-il un moyen de savoir si l'opérateur de conversion
(std::string) est défini pour les objets de la classe T ?
|
En gros, tu voudrais faire un truc du style
template<class T>
struct modele
{
T un_T;
std::string display() const
{
if (T_a_un_operateur_de_conversion)
{
return std::string (un_T);
}
else
{
throw "Conversion impossible";
}
}
};
C'est bien ça ? |
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Fri Oct 13, 2006 4:44 am Post subject: Re: pb de conversion en std::string |
|
|
On Thu, 12 Oct 2006 22:13:30 +0200, "MGN" <mgueguen (AT) metrica (DOT) fr>:
| Quote: | Ma question : y-a-t-il un moyen de savoir si l'opérateur de conversion
(std::string) est défini pour les objets de la classe T ?
Je voudrais que la conversion soit testée à l'exécution...
|
"Modern C++ design" (Alexandrescu), section 2.7 :
typedef char EstConvertible;
class PasConvertible { char dummy[2]; };
EstConvertible Test (std::string);
PasConvertible Test (...);
template <class T> struct EstConvertibleEnString
{
static bool operator ()
{
return sizeof (Test (T())) == sizeof (EstConvertible);
}
};
struct Avec
{ operator std::string() const; };
struct Sans
{ };
int main()
{
std::cerr << EstConvertibleEnString<Avec>()() << "\n"
<< EstConvertibleEnString<Sans>()() << "\n";
}
Note que tout est évalué à la compilation (comme toujours avec les
templates). Mais ça te donne un booléen, dont tu peux te servir à
l'exécution. |
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Fri Oct 13, 2006 4:48 am Post subject: Re: pb de conversion en std::string |
|
|
J'ai écrit :
| Quote: | template <class T> struct EstConvertibleEnString
{
static bool operator ()
|
Gloups... Erreur ici ! À remplacer par :
bool operator()() const
| Quote: | {
return sizeof (Test (T())) == sizeof (EstConvertible);
|
En fait, je ne sais pas pourquoi j'ai créé une classe ici. Une
fonction template aurait aussi bien convenu (enfin, je crois). |
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Fri Oct 13, 2006 6:59 am Post subject: Re: pb de conversion en std::string |
|
|
| Quote: | Ma question : y-a-t-il un moyen de savoir si l'opérateur de conversion
(std::string) est défini pour les objets de la classe T ?
Je voudrais que la conversion soit testée à l'exécution...
"Modern C++ design" (Alexandrescu), section 2.7 :
|
[Y'a que moi, sur ce thread !?]
Petite précision : le code donné ici fonctionne si un T est
convertible en un std::string. Il répond "true" avec T == char*.
S'il faut vraiment tester, à l'exécution (i.e. le code doit
impérativement compiler), si "T::operator std::string() const" existe,
ça risque d'être plus compliqué. |
|
| Back to top |
|
 |
Marc G Guest
|
Posted: Fri Oct 13, 2006 9:11 am Post subject: Re: pb de conversion en std::string |
|
|
| Quote: | S'il faut vraiment tester, à l'exécution (i.e. le code doit
impérativement compiler), si "T::operator std::string() const" existe,
ça risque d'être plus compliqué.
en fait, c'est une question plus théorique que pratique. |
Comme tu dis, avec les templates, tout se règle à la compilation et ta
solution me convient très bien.
J'ai 2 petites questions :
1) pourquoi operator()() et pas operator() simplement ?
2) Pas convertible Test(...); //<- je croyais qu'il fallait au moins
définir un paramètre dans les fonctions avec une liste de paramètres
variable...
En tout cas, merci pour ta réponse. |
|
| Back to top |
|
 |
Marc G Guest
|
Posted: Fri Oct 13, 2006 9:11 am Post subject: Re: pb de conversion en std::string |
|
|
j'ai mis en place ta solution avec une fonction template
template<class T>
bool EstConvertibleEnString()
{
T t;
return sizeof(t)==sizeof(EstConvertible);
}
nota : je ne peux pas écrire sizeof(T()), mon compilo n'apprécie pas (pb
habituel de passage par référence non constante je suppose)
mais il me reste un (gros) problème
Qd j'écris :
if (!EstConvertibleEnString<T>())
flux<<"pas convertible"<<"\n";
else
flux<<std::string(t)<<"\n";
mon compilateur refuse de compiler la dernière ligne si l'objet n'est pas
convertible , ce qui est en fait assez normal...
En fait, ça marche bien si l'objet est convertible
Tu as une idée ? |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Fri Oct 13, 2006 9:11 am Post subject: Re: pb de conversion en std::string |
|
|
Fabien LE LEZ wrote:
| Quote: | Ma question : y-a-t-il un moyen de savoir si l'opérateur de
conversion (std::string) est défini pour les objets de la
classe T ?
Je voudrais que la conversion soit testée à l'exécution...
"Modern C++ design" (Alexandrescu), section 2.7 :
[Y'a que moi, sur ce thread !?]
|
Ton posting indique 3 heures du mat'. C'est sûr qu'à cette
heure-là, je n'y suis pas.
| Quote: | Petite précision : le code donné ici fonctionne si un T est
convertible en un std::string. Il répond "true" avec T => char*.
S'il faut vraiment tester, à l'exécution (i.e. le code doit
impérativement compiler), si "T::operator std::string() const"
existe, ça risque d'être plus compliqué.
|
Qu'une classe ait une conversion en std::string ou non, ça ne
change pas lors de l'exécution. C'est bien connu déjà à la
compilation.
Ceci dit, je me méfierais beaucoup d'une telle classe. Des
opérateurs de conversion ont leur utilité dans des cas bien
précis, mais une conversion implicite en std::string, ça me
semble chercher les ennuis : des ambiguïtés ou des erreurs non
détecter par le compilateur. C'est à éviter dans le cas général.
En fait, l'idiome « standard » pour convertir un objet en
texte, c'est de fournir un opérateur <<.
--
James Kanze GABI Software
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 |
|
| Back to top |
|
 |
Marc G Guest
|
Posted: Fri Oct 13, 2006 2:27 pm Post subject: Re: pb de conversion en std::string |
|
|
| Quote: | mais il me reste un (gros) problème
Qd j'écris :
if (!EstConvertibleEnString<T>())
flux<<"pas convertible"<<"\n";
else
flux<<std::string(t)<<"\n";
mon compilateur refuse de compiler la dernière ligne si l'objet n'est pas
convertible , ce qui est en fait assez normal...
|
j'ai trouvé une solution, dans le même esprit que la fonction TestConversion
que tu as définie
std::string to_string(std::string s) { return s;}
std::string to_string(...) { return "";}
if (!EstConvertibleEnString<T>())
flux<<"pas convertible"<<"\n";
else
flux<< to_string(t)<<"\n";
et ça marche cette fois-ci !
merci beaucoup pour ton aide. |
|
| Back to top |
|
 |
Sylvain Togni Guest
|
Posted: Fri Oct 13, 2006 2:43 pm Post subject: Re: pb de conversion en std::string |
|
|
Marc G wrote:, :
| Quote: | mais il me reste un (gros) problème
Qd j'écris :
if (!EstConvertibleEnString<T>())
flux<<"pas convertible"<<"\n";
else
flux<<std::string(t)<<"\n";
mon compilateur refuse de compiler la dernière ligne si l'objet n'est pas
convertible , ce qui est en fait assez normal...
j'ai trouvé une solution, dans le même esprit que la fonction TestConversion
que tu as définie
std::string to_string(std::string s) { return s;}
std::string to_string(...) { return "";}
if (!EstConvertibleEnString<T>())
flux<<"pas convertible"<<"\n";
else
flux<< to_string(t)<<"\n";
et ça marche cette fois-ci !
|
Encore plus simple :
std::string to_string(std::string const& s) {return s;}
std::string to_string(...) {return "pas convertible";}
flux << to_string(t) << '\n';
--
Sylvain Togni |
|
| Back to top |
|
 |
Marc G Guest
|
Posted: Fri Oct 13, 2006 3:03 pm Post subject: Re: pb de conversion en std::string |
|
|
on peut aussi faire un truc du genre
bool to_string(std::string s) { return true;}
bool to_string(...) { return false;}
pour savoir à l'exécution si la conversion est possible
nota :
quand j'écris
std::string to_string(std::string const& s) {return s;}
la référence pose problème avec mon compilo (BCB6)
si je fais par exemple
std::ostringstream flux;
flux<<to_string(un_objet)<<"\n";
en fait ça plante
je pense que c'est dû au fait qu'il y a d'abord une conversion de l'objet en
une string qui est détruite qd on appelle to_string (donc il faut
impérativement passer une copie)
Qu'en penses-tu ?
Marc |
|
| Back to top |
|
 |
Michel Decima Guest
|
Posted: Fri Oct 13, 2006 3:30 pm Post subject: Re: pb de conversion en std::string |
|
|
Marc G a écrit :
| Quote: | j'ai mis en place ta solution avec une fonction template
template<class T
bool EstConvertibleEnString()
{
T t;
return sizeof(t)==sizeof(EstConvertible);
}
nota : je ne peux pas écrire sizeof(T()), mon compilo n'apprécie pas (pb
habituel de passage par référence non constante je suppose)
|
Dans le texte cite par Fabien, il n'y a pas sizeof(T()) mais
sizeof(makeT()), ou makeT est declaree comme retournant un T,
sans definition puisque inutile. Ca evite d'avoir a instancier
un objet de type T pour le code du predicat.
Mais ca n'est pas suffisant, mon g++-4.1 proteste si T est
un char[5] par exemple, par ce qu'il refuse la declaration d'une
fonction qui retourne un tableau. Avec un T*, ca passe.
Le code precedent devient:
typedef char EstConvertible;
class PasConvertible { char dummy[2]; };
template <class T> struct EstConvertibleEnString
{
static EstConvertible Test (std::string);
static PasConvertible Test (...);
static T* makeT();
enum { value = (sizeof( Test(*makeT())) == sizeof(EstConvertible)) };
bool operator()() const { return value; }
};
| Quote: | mais il me reste un (gros) problème
Qd j'écris :
if (!EstConvertibleEnString<T>())
flux<<"pas convertible"<<"\n";
else
flux<<std::string(t)<<"\n";
mon compilateur refuse de compiler la dernière ligne si l'objet n'est pas
convertible , ce qui est en fait assez normal...
En fait, ça marche bien si l'objet est convertible
|
On peut faire des choses compliquees avec de la specialisation
de classes ou fonctions templates:
struct True {}; struct False {};
template <int B> struct Boolean { typedef True type; };
template<> struct Boolean<0> { typedef False type; } ;
template <typename T>
void print(T const& value, True const& tag)
{
std::cout << "convertible: " << std::string(value) << std::endl;
}
template <typename T>
void print(T const& value, False const& tag)
{
std::cout << "pas convertible" << std::endl;
}
template <typename T>
void print(T const& value)
{
typedef typename
Boolean< IsConvertibleToString<T>::value >::type TagType;
print(value, TagType());
}
int main() {
print("toto");
print(12);
}
Mais bon, c'est surement pas la peine de sortir ce genre d'artillerie
lourde dans le cas de l'exemple que tu as propose. Si tu veux voir une
utilisation de ce genre de technique, regarde Boost.Graph, c'en est plein. |
|
| Back to top |
|
 |
Sylvain Togni Guest
|
Posted: Fri Oct 13, 2006 3:31 pm Post subject: Re: pb de conversion en std::string |
|
|
Marc G wrote:
| Quote: | quand j'écris
std::string to_string(std::string const& s) {return s;}
la référence pose problème avec mon compilo (BCB6)
si je fais par exemple
std::ostringstream flux;
flux<<to_string(un_objet)<<"\n";
en fait ça plante
je pense que c'est dû au fait qu'il y a d'abord une conversion de l'objet en
une string qui est détruite qd on appelle to_string (donc il faut
impérativement passer une copie)
Qu'en penses-tu ?
|
Passer un temporaire par référence constante ne devrait pas
poser de problème.
Je ne connaît pas BCB6 mais ça m'étonnerai qu'il ait ce genre
de bug, cela le rendrait à peu prêt inutilisable ; le plantage
doit venir d'ailleurs.
--
Sylvain Togni |
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Fri Oct 13, 2006 8:50 pm Post subject: Re: pb de conversion en std::string |
|
|
On Fri, 13 Oct 2006 08:48:03 +0200, "Marc G" <mgueguen (AT) metrica (DOT) fr>:
| Quote: | 1) pourquoi operator()() et pas operator() simplement ?
|
C'est une fonction, dont le nom est "operator()".
Pour déclarer une fonction "f", on écrit :
void f();
Pour déclarer une fonction "operator()", on écrit :
operator()();
| Quote: | 2) Pas convertible Test(...); //<- je croyais qu'il fallait au moins
définir un paramètre dans les fonctions avec une liste de paramètres
variable...
|
Pas à ma connaissance.
Note qu'appeler cette fonction serait vraisemblablement un
comportement indéfini. Mais on ne l'appelle pas (on ne la définit même
pas). |
|
| Back to top |
|
 |
Fabien LE LEZ Guest
|
Posted: Fri Oct 13, 2006 8:54 pm Post subject: Re: pb de conversion en std::string |
|
|
On Fri, 13 Oct 2006 10:45:09 +0200, "Marc G" <mgueguen (AT) metrica (DOT) fr>:
| Quote: | bool EstConvertibleEnString()
{
T t;
return sizeof(t)==sizeof(EstConvertible);
|
Gniii ? D'où sors-tu cette idée ?
Je ne vois vraiment pas pourquoi ça pourrait marcher, ni même ce que
c'est censé faire. |
|
| Back to top |
|
 |
|
|
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
|
|