overloading ou spécialisation... telle est la question

Le
AG
Bonjour,

Voici ma fonction template:

template <class C>
string ReadFile::ValToString(C in)
{
ostringstream i;
i << in;
return i.str();
}

Mais pour les classes de types string, cette fonction ne fonctionne
pas pour plusieurs raisons:
l'opérateur << s'arrête au premier espace. En plus de cela je voudrais
rajouter des guillemets.

Donc j'ai fait une specialisation (?)

template<>
string ReadFile::ValToString(string in)
{
return """ + in + """;
}

qui a l'air de marcher.

Pour les classes de types C=vector<T> ou même C=vector<vector<T> > je
voudrais rajouter des parenthèses. Donc j'ai fait:

template <>
string ReadFile::ValToString<vector<T> >(vector<T> in)
{
ostringstream i;
i << in;
return "(" + i.str() + ")";
}

cette dernière fonction n'est bien sûr jamais appelée. C'est la
fonction plus générale qui est appelée à la place. Est-ce qu'il exi=
ste
un moyen de contourner ce problème ? Je tourne sous visual.

Alexandre.

PS: j'oublierais pas de rajouter les const là ou il faut, promis :-)
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Jean-Marc Bourguet
Le #21360891
AG
Bonjour,

Voici ma fonction template:

template <class C>
string ReadFile::ValToString(C in)
{
ostringstream i;
i << in;
return i.str();
}

Mais pour les classes de types string, cette fonction ne fonctionne
pas pour plusieurs raisons:
l'opérateur << s'arrête au premier espace. En plus de cela je voudrais
rajouter des guillemets.

Donc j'ai fait une specialisation (?)

template<>
string ReadFile::ValToString(string in)
{
return """ + in + """;
}

qui a l'air de marcher.

Pour les classes de types C=vector<T> ou même C=vector<vector<T> > je
voudrais rajouter des parenthèses. Donc j'ai fait:

template <>
string ReadFile::ValToString<vector<T> >(vector<T> in)
{
ostringstream i;
i << in;
return "(" + i.str() + ")";
}

cette dernière fonction n'est bien sûr jamais appelée. C'est la
fonction plus générale qui est appelée à la place. Est-ce qu'il existe
un moyen de contourner ce problème ? Je tourne sous visual.



Tu peux essayer de donner un code minimal mais complet reproduisant le
probleme? (qu'est-ce que T ici par exemple).

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
Mickaël Wolff
Le #21361931
AG a écrit :
template <class C>
string ReadFile::ValToString(C in)
{
ostringstream i;
i << in;
return i.str();
}

Mais pour les classes de types string, cette fonction ne fonctionne
pas pour plusieurs raisons:
l'opérateur << s'arrête au premier espace. En plus de cela je voudrais
rajouter des guillemets.



Les flux fonctionnent en reconnaissant les formats de chaines. Si tu
ne veux pas que ton flux coupe les mots, il faut que tu désactive le
comportement. La fonction membre std::istream::setf avec
std::ios_base::skipws e l'entete <iomanip>.


--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
FX
Le #21363091
AG a écrit :
Pour les classes de types C=vector<T> ou même C=vector<vector<T> > je
voudrais rajouter des parenthèses. Donc j'ai fait:

template <>
string ReadFile::ValToString<vector<T> >(vector<T> in)
{
ostringstream i;
i << in;
return "(" + i.str() + ")";
}

cette dernière fonction n'est bien sûr jamais appelée. C'est la
fonction plus générale qui est appelée à la place. Est-ce qu'il existe
un moyen de contourner ce problème ? Je tourne sous visual.



Cette fonction ne compile pas chez moi, et pour cause: T n'est pas défini.

Je te propose donc plutôt:

template <class T>
string ReadFile::ValToString(vector<T> in)
{
ostringstream i;
i << in;
return "(" + i.str() + ")";
}

A condition que l'opérateur << soit défini avec un vector. Par exemple:

template <class T>
ostream& operator << (ostream &s, vector<T> &v)
{
vector<T>::iterator it;
for(it = v.begin(); it != v.end(); it++)
{
s << *it << ", ";
}
return s;
}


FX
James Kanze
Le #21363351
On Mar 11, 11:11 am, AG
Voici ma fonction template:

template <class C>
string ReadFile::ValToString(C in)
{
ostringstream i;
i << in;
return i.str();
}

Mais pour les classes de types string, cette fonction ne fonctionne
pas pour plusieurs raisons:
l'opérateur << s'arrête au premier espace. En plus de cela je voudrai s
rajouter des guillemets.

Donc j'ai fait une specialisation (?)

template<>
string ReadFile::ValToString(string in)
{
return """ + in + """;
}



C'est effectivement une specialisation. Un surcharge aurait
marché aussi, avec à peu près le même résultat.

qui a l'air de marcher.

Pour les classes de types C=vector<T> ou même C=vector<vector<T> > je
voudrais rajouter des parenthèses. Donc j'ai fait:

template <>
string ReadFile::ValToString<vector<T> >(vector<T> in)
{
ostringstream i;
i << in;
return "(" + i.str() + ")";
}



Et c'est quoi, T ?

Si j'ai bien compris, ce que tu veux, c'est une specialisation
partielle, et ça ne marche que pour les classes. Tu peux, en
revanche, surcharger un template de fonction avec un autre
template de fonction : dans le cas où la déduction de type
marche sur les deux, et les deux instantiations ne se
distinguent pas autrement, c'est celle en provenance du template
le plus spécialisé qui sera choisi. Donc, donné :

template<typename T>
std::string ReadFile::ValToString( T const& in );

template<typename T>
std::string ReadFile::ValToString( std::vector<T> const& in );

std::string ReadFile::ValToString( std::string const& in );

-- Pour la plupart des types, seulement la première est
viable ; elle sera donc choisie.

-- Pour std::string, le choix se fait entre la première et la
dernière. Dans de tels cas d'égalité, préférence est donnée
à la fonction qui n'est pas une instance d'un template.

-- Pour std::vector<int>, etc., le choix se fait entre la
première et la deuxième, avec préférence pour la deuxième,
parce que le template dont elle provient est plus
specialisé.

--
James Kanze
Fabien LE LEZ
Le #21363341
On Thu, 11 Mar 2010 22:18:12 +0100, FX
template <class T>
ostream& operator << (ostream &s, vector<T> &v)
{
vector<T>::iterator it;



Attention, il manque les "const" un peu partout ici.
AG
Le #21364321
On Mar 11, 4:18 pm, Jean-Marc Bourguet
Tu peux essayer de donner un code minimal mais complet reproduisant le
probleme?  (qu'est-ce que T ici par exemple).



Bonjour Jean-Marc.

Oui voilà mon code minimal qui compile, tourne, mais ne fonctionne
pas. Je remarque que les autres on répondu, donc je vais voir ce
qu'ils disent. mais en attendant voilà mon code, sans les const un peu
partout comme il a déjà été fait remarqué. Je regarde les autres
réponses.

#include <iostream>
#include <sstream>
#include <vector>
#include <string>

using namespace std;

template<class C> ostream & operator<<(ostream &o, vector<C> v);

class A
{
public:
template<class C>
string ValToString(C & in);
template<class C>
string ValToString(vector<C> & in);
};

int main(int argc, char * argv[])
{
A a;
int i=3;
vector<int> v;
v.push_back(1);
v.push_back(3);
v.push_back(4);
cout cout }

template<class C>
string A::ValToString(C &in)
{
ostringstream buff;
buff << in;
return buff.str();
}

template<class C>
string A::ValToString(std::vector<C> &in)
{
ostringstream buff;
buff << in;
return "(" + buff.str() + ")";
}

template<class C>
ostream & operator<<(ostream &o, vector<C> v)
{
vector<C>::iterator i;
for(i=v.begin();i!=v.end();++i)
{
o << *i << " ";
}
o << "n";
return o;
}
AG
Le #21364401
On Mar 11, 11:42 pm, James Kanze
 -- Pour std::vector<int>, etc., le choix se fait entre la
    première et la deuxième, avec préférence pour la deuxiè me,
    parce que le template dont elle provient est plus
    specialisé.


Bonjour James,

Dans l'exemple du code que j'ai posté plus haut, il semble que mon
compilo choisisse la première au lieu de la deuxième (les partenthèse s
ne sont pas affichées). J'ai Visual C++ Express 2008.

Alexandre.
Jean-Marc Bourguet
Le #21364471
AG
On Mar 11, 4:18 pm, Jean-Marc Bourguet > Tu peux essayer de donner un code minimal mais complet reproduisant le
> probleme?  (qu'est-ce que T ici par exemple).

Bonjour Jean-Marc.

Oui voilà mon code minimal qui compile, tourne, mais ne fonctionne
pas. Je remarque que les autres on répondu, donc je vais voir ce
qu'ils disent. mais en attendant voilà mon code, sans les const un peu
partout comme il a déjà été fait remarqué. Je regarde les autres
réponses.

#include <iostream>
#include <sstream>
#include <vector>
#include <string>

using namespace std;

template<class C> ostream & operator<<(ostream &o, vector<C> v);

class A
{
public:
template<class C>
string ValToString(C & in);
template<class C>
string ValToString(vector<C> & in);
};

int main(int argc, char * argv[])
{
A a;
int i=3;
vector<int> v;
v.push_back(1);
v.push_back(3);
v.push_back(4);
cout cout

cout
Ton parametre template est int, pas vector<int> si tu veux la deuxieme
surcharge.

}

template<class C>
string A::ValToString(C &in)
{
ostringstream buff;
buff << in;
return buff.str();
}

template<class C>
string A::ValToString(std::vector<C> &in)
{
ostringstream buff;
buff << in;
return "(" + buff.str() + ")";
}

template<class C>
ostream & operator<<(ostream &o, vector<C> v)
{
vector<C>::iterator i;
for(i=v.begin();i!=v.end();++i)
{
o << *i << " ";
}
o << "n";
return o;
}



--
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
AG
Le #21364641
On Mar 12, 11:21 am, Jean-Marc Bourguet
Ton parametre template est int, pas vector<int> si tu veux la deuxieme
surcharge.



well well well: ok, si je met <int> ça marche. indeed.

Mais je voudrais pouvoir utiliser ValToString<vector<int> >(v):

c'est pas possible ?

AG.
Jean-Marc Bourguet
Le #21365211
AG
On Mar 12, 11:21 am, Jean-Marc Bourguet > Ton parametre template est int, pas vector<int> si tu veux la deuxieme
> surcharge.

well well well: ok, si je met <int> ça marche. indeed.

Mais je voudrais pouvoir utiliser ValToString<vector<int> >(v):

c'est pas possible ?



Tu peux ne pas mettre de <> du tout: ValToString(v)

mais pour faire ce que tu veux, ce n'est plus de la surcharge mais de la
specialisation partielle qu'il faut et ce n'est possible qu'avec les
classes. Donc il faut faire intervenir une classe, par exemple dans
l'implementation de ValToString qui peut donc ne plus etre surchargee.

#include <iostream>
#include <sstream>
#include <vector>
#include <string>

using namespace std;

template<class C> ostream & operator<<(ostream &o, vector<C> v);

class A
{
public:
template<class C>
string ValToString(C& in);
};

int main(int argc, char * argv[])
{
A a;
int i=3;
vector<int> v;
v.push_back(1);
v.push_back(3);
v.push_back(4);
cout << "3 -> " << a.ValToString(i) << "n";
cout << "{1,3,4} -> " << a.ValToString(v);
}

template <class C>
struct B
{
B(C& v) : myC(v) {}
operator string() {
ostringstream buff;
buff << myC;
return buff.str();
}
C& myC;
};

template <class C>
struct B<vector<C> >
{
B(vector<C>& v) : myC(v) {}
operator string() {
ostringstream buff;
buff << myC;
return "(" + buff.str() + ")";

}
vector<C>& myC;
};

template<class C>
string A::ValToString(C& in)
{
return B<C>(in);
}

template<class C>
ostream & operator<<(ostream &o, vector<C> v)
{
typename vector<C>::iterator i;
for(i=v.begin();i!=v.end();++i)
{
o << *i << " ";
}
o << "n";
return o;
}

--
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
Publicité
Poster une réponse
Anonyme