OVH Cloud OVH Cloud

Template & Spécialisation

10 réponses
Avatar
Stephane Wirtel
Bonjour à tous,

Voilà, je me pose le problème suivant :

Source :
--------

#include <iostream>
#include <string>

template <class T> void Print (const T& pValue) {
std::cout << "Print Generic : " << pValue << std::endl;
}

template <> void Print<int> (const int& pValue) {
std::cout << "Print : Int : " << pValue << std::endl;
}

template <> void Print<std::string> (const std::string& pValue) {
std::cout << "Print : String : " << pValue << std::endl;
}

int main (int argc, char **argv)
{
Print ("Implicit");
Print<std::string> ("Explicit");
Print (10);
Print (10.20);
return 0;
}

Résultat :
----------

Print Generic : Implicit
Print : String : Explicit
Print : Int : 10
Print Generic : 10.2


Est-ce normal que pour 'Print ("Implicit")' j'ai le résultat 'Print Generic : Implicit' ?

N'aurais-je pas dû avoir 'Print : String : Implicit' à la place ?

compilateur : g++ 3.4.3

Merci

10 réponses

Avatar
Stephane Wirtel
Bonjour,
Print<char*> ("Implicit") correspond mieux à l'appel que Print<std::string>
(std::string("Implicit"))
voila pourquoi.
Je m'en doutais un petit peu, mais comment faire pour qu'il le prenne comme étant un std::string ?


Avatar
Stephane Wirtel
En fait, j'essaie de créer une fonction générique qui retourne toujours un std::string, afin de le mettre dans une map.
Avatar
Ahmed MOHAMED ALI
Bonjour,
Print<char*> ("Implicit") correspond mieux à l'appel que Print<std::string>
(std::string("Implicit"))
voila pourquoi.

Ahmed


"Stephane Wirtel" wrote in message
news:d40idh$81p$
Bonjour à tous,

Voilà, je me pose le problème suivant :

Source :
--------

#include <iostream>
#include <string>

template <class T> void Print (const T& pValue) {
std::cout << "Print Generic : " << pValue << std::endl;
}

template <> void Print<int> (const int& pValue) {
std::cout << "Print : Int : " << pValue << std::endl;
}

template <> void Print<std::string> (const std::string& pValue) {
std::cout << "Print : String : " << pValue << std::endl;
}

int main (int argc, char **argv)
{
Print ("Implicit");
Print<std::string> ("Explicit");
Print (10);
Print (10.20);
return 0;
}

Résultat :
----------

Print Generic : Implicit
Print : String : Explicit
Print : Int : 10
Print Generic : 10.2


Est-ce normal que pour 'Print ("Implicit")' j'ai le résultat 'Print
Generic : Implicit' ?


N'aurais-je pas dû avoir 'Print : String : Implicit' à la place ?

compilateur : g++ 3.4.3

Merci


Avatar
Jean-Marc Bourguet
Stephane Wirtel writes:

template <class T> void Print (const T& pValue) {
template <> void Print<int> (const int& pValue) {
template <> void Print<std::string> (const std::string& pValue) {

int main (int argc, char **argv)
{
Print ("Implicit");
Print<std::string> ("Explicit");
Print (10);
Print (10.20);
return 0;
}

Résultat :
----------

Print Generic : Implicit
Print : String : Explicit
Print : Int : 10
Print Generic : 10.2


Est-ce normal que pour 'Print ("Implicit")' j'ai le
résultat 'Print Generic : Implicit' ?


Oui. Le type de "Implicit" n'est pas std::string mais
char const[9], donc tu n'appelles pas la version spécialisée
pour std::string. Peut-être plus surprenant,

template <> void Print<char const*> (char const* const& pValue) {
std::cout << "Print : char const* : " << pValue << std::endl;
}

ne serait pas non plus utilisée. Il faut:

typedef char const array[9];
template <> void Print<array>(array const& pValue) {
std::cout << "Print : char const [9] : " << pValue << std::endl;
}

Mais gcc (3.3.4 en tout cas) a un bug et il faut enlever le
const au typedef.

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
Christophe de Vienne
Stephane Wirtel wrote:

Bonjour,
Print<char*> ("Implicit") correspond mieux à l'appel que
Print<std::string> (std::string("Implicit"))
voila pourquoi.
Je m'en doutais un petit peu, mais comment faire pour qu'il le prenne

comme étant un std::string ?


Surcharger Print<const char *>() ?

A+

Christophe


Avatar
Jean-Marc Bourguet
Christophe de Vienne writes:

Stephane Wirtel wrote:

Bonjour,
Print<char*> ("Implicit") correspond mieux à l'appel que
Print<std::string> (std::string("Implicit"))
voila pourquoi.
Je m'en doutais un petit peu, mais comment faire pour qu'il le prenne

comme étant un std::string ?


Surcharger Print<const char *>() ?


Ça ne sert à rien dans ce cas. Voir mon message.

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
Alexandre
Print ("Implicit");


"Implicit" n'est pas du type std::string. Donc il te faudra appeler
Print(std::string("Implicit"))
ou redéfinir ton template pour les char *.

Avatar
Jean-Marc Bourguet
"Alexandre" writes:

Print ("Implicit");


"Implicit" n'est pas du type std::string. Donc il te faudra appeler
Print(std::string("Implicit"))
ou redéfinir ton template pour les char *.


Non. Voir

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
Fabien LE LEZ
On 18 Apr 2005 17:51:24 +0200, Jean-Marc Bourguet :

Est-ce normal que pour 'Print ("Implicit")' j'ai le
résultat 'Print Generic : Implicit' ?


[...] Peut-être plus surprenant,

template <> void Print<char const*> (char const* const& pValue) {
std::cout << "Print : char const* : " << pValue << std::endl;
}

ne serait pas non plus utilisée.


Et quid de

void Print (char const* const& pValue)

?


--
;-)


Avatar
Jean-Marc Bourguet
Fabien LE LEZ writes:

On 18 Apr 2005 17:51:24 +0200, Jean-Marc Bourguet :

Est-ce normal que pour 'Print ("Implicit")' j'ai le
résultat 'Print Generic : Implicit' ?


[...] Peut-être plus surprenant,

template <> void Print<char const*> (char const* const& pValue) {
std::cout << "Print : char const* : " << pValue << std::endl;
}

ne serait pas non plus utilisée.


Et quid de

void Print (char const* const& pValue)


Ça ne change rien: la spécialisation sur char const[9] est
toujours meilleure est donc sera générée si elle n'est pas
explicite. Pour que la conversion implicite
tableau->pointeur intervienne, il faut qu'il n'y ait pas de
template en vue.

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