Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1370 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [C++] Spécialisation d'une fonction template un peu tordue...

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C++] Spécialisation d'une fonction template un peu tordue...

n°1964164
MrDiablo
Que l'Achtuche soit avec vous.
Posté le 09-02-2010 à 13:35:42  profilanswer
 

Bonjour
 
J'ai une question à laquelle je n'arrive pas à trouver de solution : j'ai une fonction template que je voudrais spécialiser pour une instance d'une classe template.
 
Un exemple valant mieux qu'un long discourt, voici mon cas. J'ai la classe templatisée suivante :

Code :
  1. template<class T>
  2. class Size
  3. {
  4. public :
  5.   T width;
  6.   T height;
  7. };


Ainsi que la fonction template suivante :

Code :
  1. template<class T>
  2. bool IsEqual(const T & a, const T & b)
  3. {
  4.   return (a == b);
  5. }


Bien évidemment, il y a eut des spécialisations pour cette méthode (notamment pour les cas des doubles).
 
L'idée serait de spécialiser IsEqual avec la class Size, histoire d'avoir un code similaire à ça :

Code :
  1. template<class T>
  2. bool IsEqual(const Size<T> & a, const Size<T> & b)
  3. {
  4.   return IsEqual<T>(a.width, b.width) && IsEqual<T>(a.height, b.height);
  5. }


Bien évidemment, ça ne marche pas (sinon je ne posterais pas là ^^)... pour spécialiser, il faut que je spécifie "template<>"   j'ai beau cherché, je ne trouve pas de solutions :/ Enfin si, j'ai une solution, mais qui ne me convient pas vraiment (elle a le mérite de marcher au moins) : c'est de surdéfinir l'opérateur == de Size :

Code :
  1. inline bool operator==( const Size & size ) const
  2. {
  3.   return ivs::IsEqual<T>(width, size.width) && ivs::IsEqual<T>(height, size.height);
  4. }


(c'est ce que je fais pour le moment, faute de mieux)
 
Auriez vous une idée de réaliser la chose ? Un grand merci par avance ;)

Message cité 1 fois
Message édité par MrDiablo le 09-02-2010 à 13:57:18
mood
Publicité
Posté le 09-02-2010 à 13:35:42  profilanswer
 

n°1964174
Un Program​meur
Posté le 09-02-2010 à 14:16:44  profilanswer
 

MrDiablo a écrit :

Bonjour
 
J'ai une question à laquelle je n'arrive pas à trouver de solution : j'ai une fonction template que je voudrais spécialiser pour une instance d'une classe template.
 
Un exemple valant mieux qu'un long discourt, voici mon cas. J'ai la classe templatisée suivante :

Code :
  1. template<class T>
  2. class Size
  3. {
  4. public :
  5.   T width;
  6.   T height;
  7. };


Ainsi que la fonction template suivante :

Code :
  1. template<class T>
  2. bool IsEqual(const T & a, const T & b)
  3. {
  4.   return (a == b);
  5. }


Bien évidemment, il y a eut des spécialisations pour cette méthode
(notamment pour les cas des doubles).


 
Ca ne me semble pas evident du tout.  Je ne vois pas comment faire une
telle specialisation qui tienne la route.
 

Citation :

L'idée serait de spécialiser IsEqual avec la class Size, histoire d'avoir un code similaire à ça :

Code :
  1. template<class T>
  2. bool IsEqual(const Size<T> & a, const Size<T> & b)
  3. {
  4.   return IsEqual<T>(a.width, b.width) && IsEqual<T>(a.height, b.height);
  5. }


Bien évidemment, ça ne marche pas (sinon je ne posterais pas là ^^)... pour
spécialiser, il faut que je spécifie "template<>"


 
Ce que tu ecris n'est pas une specialisation, mais une surcharge.  Et ca
devrait fonctionner sans probleme.  En tout cas

Code :
  1. #include <iostream>
  2. template <class T>
  3. class Size
  4. {
  5. public:
  6.     T width;
  7.     T height;
  8. };
  9. template <class T>
  10. bool isEqual(T const& a, T const& b)
  11. {
  12.     std::cout << "isEqual<T>(T const&, T const& );\n";
  13.     return true;
  14. }
  15. template <class T>
  16. bool isEqual(Size<T> const&a, Size<T> const& b)
  17. {
  18.     std::cout << "isEqual<T>(Size<T> const&, Size<T> const& )\n";
  19.     return isEqual(a.width, b.width) && isEqual(a.height, b.height);
  20. }
  21. int main()
  22. {
  23.     int a, b;
  24.     Size<int> c, d;
  25.     isEqual(a, b);
  26.     isEqual(c, d);
  27.     return 0;
  28. }


 
a le comportement auquel je m'attends.  (Note que j'ai ecrit
isEqual(a.width, b.width) et non isEqual<T>(a.width, b.width) pour
permettre a une eventuelle autre surcharge de jouer son role).
 
Une specialisation partielle s'ecrirait

Code :
  1. template <>
  2. template <class T>
  3. bool isEqual(Size<T> const&a, Size<T> const& b)
  4. {
  5. ...
  6. }


Mais effectivement, on ne peut pas specialiser partiellement une fonction.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
n°1964184
MrDiablo
Que l'Achtuche soit avec vous.
Posté le 09-02-2010 à 15:10:39  profilanswer
 

En tout premier lieu, merci pour ta réponse ;)
 

Un Programmeur a écrit :


Ca ne me semble pas evident du tout.  Je ne vois pas comment faire une
telle specialisation qui tienne la route.


Effectivement (et c'est pour cette raison que j'ai posté, c'est bien la première fois que je demande de l'aide ainsi).
 

Citation :


Ce que tu ecris n'est pas une specialisation, mais une surcharge.  Et ca
devrait fonctionner sans probleme.


Exactement. Je n'ai pas dit qu'il s'agissait d'une spécialisation, mais d'une solution (qui me permet d'avancer et d'éviter de rester coincer sur le sujet... au moins, j'ai un programme qui tourne, même si ce n'est pas l'idéal). J'en ai parlé pour éviter qu'elle soit aborder ;)
 

Citation :


Mais effectivement, on ne peut pas specialiser partiellement une fonction.


Rien à redire ^^

n°1964188
Un Program​meur
Posté le 09-02-2010 à 15:25:45  profilanswer
 

MrDiablo a écrit :


Effectivement (et c'est pour cette raison que j'ai posté, c'est bien la première fois que je demande de l'aide ainsi).


 
Tu ici parlais des doubles.  Je faisais allusion au fait qu'une specialisation pour les doubles faisant intervenir un epsilon a toutes les chances de ne pas etre transitive ce qui, en plus du probleme de determination d'un epsilon adequat, va la rendre aussi problematique que la version avec l'operateur ==.
 
Les flottants, c'est delicats.
 


---------------
The truth is rarely pure and never simple (Oscar Wilde)
n°1964250
GrosBocdel
Posté le 09-02-2010 à 19:01:19  profilanswer
 

Un Programmeur a écrit :


 
Tu ici parlais des doubles.  Je faisais allusion au fait qu'une specialisation pour les doubles faisant intervenir un epsilon a toutes les chances de ne pas etre transitive ce qui, en plus du probleme de determination d'un epsilon adequat, va la rendre aussi problematique que la version avec l'operateur ==.
 
Les flottants, c'est delicats.
 


Code :
  1. template<class T>
  2. class Size
  3. {
  4. public :
  5.   T width;
  6.   T height;
  7. bool operator==( const Size &a) const
  8. {
  9.         return ((this->width==a.width) && (this->height==a.height));
  10. }
  11. };
  12. template<class T>
  13. bool isEqual(const T &a, const T &b) {return a==b;}


c'est pas bon? (mis à part l'égalité de floats)


Message édité par GrosBocdel le 09-02-2010 à 19:01:45
n°1964254
Un Program​meur
Posté le 09-02-2010 à 19:06:45  profilanswer
 

À première vue, trois problèmes.  Ça n'utilise pas isEqual (qui peut être spécialisé ou surchargé) pour comparer les membres, ça ajoute un opérateur== qui peut ne pas être désiré, l'opérateur== n'est pas symétrique (visible si il y a des conversions implicites vers Size<T> ).


---------------
The truth is rarely pure and never simple (Oscar Wilde)
n°1964255
GrosBocdel
Posté le 09-02-2010 à 19:21:19  profilanswer
 

Un Programmeur a écrit :

l'opérateur== n'est pas symétrique (visible si il y a des conversions implicites vers Size<T> ).


T'as un exemple là dessus?

n°1969928
jesus_chri​st
votre nouveau dieu
Posté le 28-02-2010 à 00:44:53  profilanswer
 

Code :
  1. class DoubleSize
  2. {
  3. public:
  4.     operator Size< double >() const;
  5.     // some more code
  6. private:
  7.     double w;
  8.     double h;
  9. };
  10. Size< double > x;
  11. DoubleSize y;
  12. x == y; // toujours ok
  13. y == x; // marche pas avec ton code, mettre operator== en free fonction, ou friend function.


 
J'avoue que souvent je mets aussi operator== en methode membre par pure flemme, mais c'est pas bien, sauf si t'es absolument certain que ton type ne sera pas dérivé, implicit-casté etc...

n°1969941
Joel F
Real men use unique_ptr
Posté le 28-02-2010 à 08:06:08  profilanswer
 

les opérateurs binaires, sauf semantique spéciale n'ont pas a etre membre ou friend. Des fonctions libres suffisent.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [C++] Spécialisation d'une fonction template un peu tordue...

 

Sujets relatifs
Ajouter case à cocher dans fonction javascript en langage Word[C/C++] Transformation de fichiers
Programmer Acquisition de données en C++/VBModification du template universatil joomla
connaitre la taille d'un fichier en C[Résolu] Exercice C, structure, type, compilation modulaire
VBA Fin de la fonction je reviens dans ma boucle ???[RESOLU] Soucis avec mysql_fetch_array dans une fonction
[C] Lire un fichier . txt[C/SDL] undefined reference to mes fonction
Plus de sujets relatifs à : [C++] Spécialisation d'une fonction template un peu tordue...


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR