OVH Cloud OVH Cloud

Specialisation de fonctions templates

10 réponses
Avatar
Fabien LE LEZ
Bonjour,

La question idiote du jour : à quoi sert la spécialisation de
fonctions templates ?

Par exemple, soit la fonction suivante :

template <class T> void f (T const&);

Y a-t-il une bonne raison d'écrire

template<> void f (std::string const&);

au lieu de

void f (std::string const&);

?

Merci d'avance...


--
;-)

10 réponses

Avatar
Loïc Joly
Fabien LE LEZ wrote:

Bonjour,

La question idiote du jour : à quoi sert la spécialisation de
fonctions templates ?


Il y a pas mal de cas où ça peut être utile :
- Spécialiser un paramètre qui n'est pas un type
- Spécialiser une fonction template membre d'une classe sans modifier la
classe
- Spécialiser template <class T> T rand();
- Si on déclare une fonction template comme friend


--
Loïc

Avatar
Alexandre
La question idiote du jour : à quoi sert la spécialisation de
fonctions templates ?


dans les cas particuliers, où le cas général ne marche pas.


Par exemple, soit la fonction suivante :

template <class T> void f (T const&);

Y a-t-il une bonne raison d'écrire

template<> void f (std::string const&);

au lieu de

void f (std::string const&);

?


ça dépend de f !!
Mais en voici un :

template <class T>
T min(T a, T b) // c'est mieux avec des const& mais bon c'est pour
aller vite
{
if(a<b)
return a;
else
return b;
}

le patron marche pour tout, sauf pour.... une chaine type C (char *) parce
que la comparaison, existant bel et bien, ne compare pas deux chaines mais
deux adresses !!! Alors SI TU VEUX que le patron fonctionne avec des (char
*) (ce qui n'est pas bien sur une obligation), il faut le spécialiser :
template<> char* min(char *a, char *b)
{
if(strcmp(a,b)<0)
return a;
else
return b;
}

autre raison : optimiser pour un type particulier ! (par exemple le
vector<bool>)

En espérant avoir été clair,
Alexandre


Merci d'avance...


--
;-)


Avatar
Franck Bredat
Bonjour,

La question idiote du jour : à quoi sert la spécialisation de
fonctions templates ?

Par exemple, soit la fonction suivante :

template <class T> void f (T const&);

Y a-t-il une bonne raison d'écrire

template<> void f (std::string const&);

au lieu de

void f (std::string const&);

?

Merci d'avance...




si le compilateur tombe sur la declation de la fonction template et
celle de la declaration de la fonction simple, celles-ci entreront en
conflit lors d'un appel a f avec un std::string : il y a une erreur de
compile car il y a du coup deux pretendants !

En specialisant la fonction template, il n'y a plus de conflit possible.

Voila.

Avatar
drkm
Franck Bredat writes:

si le compilateur tombe sur la declation de la fonction template et
celle de la declaration de la fonction simple, celles-ci entreront en
conflit lors d'un appel a f avec un std::string : il y a une erreur de
compile car il y a du coup deux pretendants !

En specialisant la fonction template, il n'y a plus de conflit possible.


Tiens. Je pensais que l'instanciation d'un modèle de fonction
constituait une moins bonne correspondance qu'une fonction de même
signature [*].

[*] Je veux dire même signature que celle que donne
l'instanciation.

--drkm

Avatar
Fabien LE LEZ
On Fri, 15 Oct 2004 01:57:03 +0200, Franck Bredat :

si le compilateur tombe sur la declation de la fonction template et
celle de la declaration de la fonction simple, celles-ci entreront en
conflit


Non.

Par contre, ce qui m'a fait penser à cette question, c'est le chapitre
7 de "Exceptional C++ Style", à savoir :

template <class T> void f (T); // 1
template <> void f<int*> (int*); // 2
template <class T> void f (T*); // 3

int main()
{
int *p;
f (p); // Appelle [3], pas [2] !
}


--
;-)

Avatar
Gabriel Dos Reis
Fabien LE LEZ writes:

| Bonjour,
|
| La question idiote du jour : à quoi sert la spécialisation de
| fonctions templates ?

À spécialiser un template :-)

à peu près pour les mêmes raisons que pour une classe.

| Par exemple, soit la fonction suivante :
|
| template <class T> void f (T const&);
|
| Y a-t-il une bonne raison d'écrire
|
| template<> void f (std::string const&);
|
| au lieu de
|
| void f (std::string const&);
|
| ?

Une surcharge participe à la résolution de surcharge, alors qu'une
spécialisation non. Pour une spécialisation, seule la fonction
template primaire (quel est le bon mot pour « primary function
template » ?) participe au tounois de la résolution de surcharge.
Si elle gagne, elle va déléguer le boulot (i.e. la définition) à la
fonction spécialisée.

Au final, tout est question de design -- il y a des endroits où je
voudrais une spécialisation et d'autres ou je voudrais une surcharge.

-- Gaby
Avatar
Gabriel Dos Reis
Franck Bredat writes:

| > Bonjour,
| >
| > La question idiote du jour : à quoi sert la spécialisation de
| > fonctions templates ?
| >
| > Par exemple, soit la fonction suivante :
| >
| > template <class T> void f (T const&);
| >
| > Y a-t-il une bonne raison d'écrire
| >
| > template<> void f (std::string const&);
| >
| > au lieu de
| >
| > void f (std::string const&);
| >
| > ?
| >
| > Merci d'avance...
| >
| >
|
| si le compilateur tombe sur la declation de la fonction template et
| celle de la declaration de la fonction simple, celles-ci entreront en
| conflit lors d'un appel a f avec un std::string : il y a une erreur de
| compile car il y a du coup deux pretendants !

Non.

| En specialisant la fonction template, il n'y a plus de conflit possible.

Non.

-- Gaby
Avatar
Gabriel Dos Reis
Fabien LE LEZ writes:

| On Fri, 15 Oct 2004 01:57:03 +0200, Franck Bredat :
|
| >si le compilateur tombe sur la declation de la fonction template et
| >celle de la declaration de la fonction simple, celles-ci entreront en
| >conflit
|
| Non.
|
| Par contre, ce qui m'a fait penser à cette question, c'est le chapitre
| 7 de "Exceptional C++ Style", à savoir :

Je crois que le titre de ce chapitre est « Why Not Specialize Function
Templates ? »

J'aurais pris la négation de toutes assertions comme réponse à ta
question ;-p

-- Gaby
Avatar
Fabien LE LEZ
On 15 Oct 2004 18:10:02 +0200, Gabriel Dos Reis
:

J'aurais pris la négation de toutes assertions comme réponse à ta
question ;-p


Toi, oui, je n'en doute pas. Perso je préfère bien programmer ;-P


--
;-)

Avatar
Fabien LE LEZ
On Thu, 14 Oct 2004 20:51:24 +0200, "Alexandre"
:

Alors SI TU VEUX que le patron fonctionne avec des (char
*) (ce qui n'est pas bien sur une obligation), il faut le spécialiser :
template<> char* min(char *a, char *b)
{
if(strcmp(a,b)<0)
return a;
else
return b;
}


Et en quoi est-ce mieux que la surcharge ?

char* min(char *a, char *b)
{
if(strcmp(a,b)<0)
return a;
else
return b;
}


--
;-)