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

  FORUM HardWare.fr
  Programmation
  C++

  Metaprogrammation: Comment détecter si une fonction existe ou pas

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Metaprogrammation: Comment détecter si une fonction existe ou pas

n°1699053
papangue
Posté le 07-03-2008 à 17:12:17  profilanswer
 

Bonjour,
Dans un code j'aimerai faire le test suivant:
 
     Si la fonction

Code :
  1. template<class T>
  2. stream&<<(stream&,T& )


existe alors je l'utilise, sinon je ne fais rien
 
Normalement pour ca c'est les traits qu'on utilise. Par contre je n'arrive pas à voir comment (et si c'est possible) de tester la présence d'une fonction sans générer de compile time assertion. J'insiste sur ce dernier point!
 
Si vous avez une idée?
 
Merci,

mood
Publicité
Posté le 07-03-2008 à 17:12:17  profilanswer
 

n°1699071
Joel F
Real men use unique_ptr
Posté le 07-03-2008 à 17:45:09  profilanswer
 

c'est chelou. Faut trouver un cadre dans lequel tu va pouvoir utilisait la SFINAE. Le problème est que, si al fonction existe pas, bah tu pourra guère tenter de l'utiliser sans erreur de compil.
Ca serait une méthode ça aurait pu etre réglé à coup de boost:has_xxx masi en fonction libre :/

Message cité 1 fois
Message édité par Joel F le 07-03-2008 à 18:19:39
n°1699569
papangue
Posté le 09-03-2008 à 19:38:18  profilanswer
 

Joel F a écrit :

c'est chelou. Faut trouver un cadre dans lequel tu va pouvoir utilisait la SFINAE. Le problème est que, si al fonction existe pas, bah tu pourra guère tenter de l'utiliser sans erreur de compil.
Ca serait une méthode ça aurait pu etre réglé à coup de boost:has_xxx masi en fonction libre :/


 
 
Merci pour ta réponse.
C'est exactement juste la réponse qu'il me fallait, compléter avec un peu de google. En utilisant la SFINAE il est possible de checker l'existence de fonctions membres ou même non membre comme dans mon cas.
Merci Joel pour cette info - j'en ai au passage profiter pour apprendre, comprendre ce que l'on pouvait faire avec cette bete.
 
pour ce qui est de ça:

Citation :

Le problème est que, si al fonction existe pas, bah tu pourra guère tenter de l'utiliser sans erreur de compil.


 
l'utilisation de la SFINAE permet de checker l'existence d'une méthode (membre ou non membre) sans erreur de compile. Ensuite avec le résultat renvoyer par ce mécanisme, rien ne m'empêche d'écrire une class template avec un paramètre bool, et de specialiser avec: true j'utilise la méthode puisqu'elle existe, false et bien je fait rien!
 
Juste pour ceux qui veulent des info pour comprendre comment ca marche, j'ai un lien assez sympa:
http://www.codeproject.com/KB/arch [...] etection12
 
Joel si tu as de la doc un peu plus poussée sur le sujet, je suis preneur!
 
juste pour illustration, un code test que j'ai écrit pour comprendre:
le fichier .h contenant l'ensemble des class et structure nécessaire à la mise en place de ce petit mécanisme:

Code :
  1. #include <ostream>
  2. class toto
  3. {};
  4. class tata
  5. {};
  6. std::basic_ostream<char>& operator<<(std::basic_ostream<char>& stream, const toto& value)
  7. {
  8. return stream;
  9. }
  10. typedef char NotFound; 
  11. struct Found { char x[2]; };
  12. /**
  13. Structure to find functions like std::basic_ostream<char>& std::basic_ostream<char>::operator<<(T)
  14. */
  15. template <class T, std::basic_ostream<char>&  (std::basic_ostream<char>::*)(T) >
  16. struct TestNonStatic_ostream { };
  17. template<class T>
  18. static Found Test_ostream(TestNonStatic_ostream<T,&std::basic_ostream<char>::operator<< >*);
  19. template<class T>
  20. static NotFound Test_ostream( ... );
  21. /**
  22. Structure to find functions like std::basic_ostream<char>& operator<<(std::basic_ostream<char>&, const T& )
  23. */
  24. template <class T, std::basic_ostream<char>& (*)(std::basic_ostream<char>&,const T& ) >
  25. struct TestNonStatic_operator_ref_const { };
  26. template<class T>
  27. static Found Test_operator_ref_const(TestNonStatic_operator_ref_const<T,&operator<< >*);
  28. template<class T>
  29. static NotFound Test_operator_ref_const( ... );
  30. /**
  31. Structure to find functions like std::basic_ostream<char>& operator<<(std::basic_ostream<char>&, T& )
  32. */
  33. template <class T, std::basic_ostream<char>& (*)(std::basic_ostream<char>&, T& ) >
  34. struct TestNonStatic_operator_ref { };
  35. template<class T>
  36. static Found Test_operator_ref(TestNonStatic_operator_ref<T,&operator<< >*);
  37. template<class T>
  38. static NotFound Test_operator_ref( ... );
  39. /**
  40. Structure to find functions like std::basic_ostream<char>& operator<<(std::basic_ostream<char>&, T)
  41. */
  42. template <class T, std::basic_ostream<char>& (*)(std::basic_ostream<char>&, T) >
  43. struct TestNonStatic_operator { };
  44. template<class T>
  45. static Found Test_operator(TestNonStatic_operator<T,&operator<< >*);
  46. template<class T>
  47. static NotFound Test_operator( ... );
  48. template<class T>
  49. struct test
  50. {
  51. static const bool check_presence = (sizeof( Test_ostream<T>    ( 0 ) ) == sizeof(Found)) ||
  52.            (sizeof( Test_operator_ref_const<T> ( 0 ) ) == sizeof(Found)) ||
  53.            (sizeof( Test_operator_ref<T>  ( 0 ) ) == sizeof(Found)) ||
  54.            (sizeof( Test_operator<T>   ( 0 ) ) == sizeof(Found));
  55. };


 
et maintenant le programme principale:

Code :
  1. int main(/*int argc, _TCHAR* argv[]*/)
  2. {
  3. bool test_ = test<int>::check_presence;          // vaut true car la méthode est définit dans la STL
  4. test_ = test<toto>::check_presence;              // vaut true car la méthode est définit dans le .h précédent!
  5. test_ = test<tata>::check_presence;              // vaut false car pas de méthode définit
  6. return 0;
  7. }


 
 
Cdt,

n°1699608
Joel F
Real men use unique_ptr
Posté le 09-03-2008 à 20:53:35  profilanswer
 

papangue a écrit :


l'utilisation de la SFINAE permet de checker l'existence d'une méthode (membre ou non membre) sans erreur de compile. Ensuite avec le résultat renvoyer par ce mécanisme, rien ne m'empêche d'écrire une class template avec un paramètre bool, et de specialiser avec: true j'utilise la méthode puisqu'elle existe, false et bien je fait rien!

 

Ca m'était sorti de la tête, je cherchais à checker qqchose de plus complexe avec un BOOST_TYPEOF, ta solution est bien meilleur.
L'astuce du type de retour de taille différente et de l'utilisation de l'ellipse pour desambiguer est à la base de 51254289 astuces du mêmes genres d'ailleurs.

 
papangue a écrit :


Joel si tu as de la doc un peu plus poussée sur le sujet, je suis preneur!


A part une greffe de cerveau, je n'ai rien à te proposer pour l'instant. N'hésite pas à me contacter ultérieurement si tu cherches d'autre infos.


Message édité par Joel F le 09-03-2008 à 20:57:32
n°1699697
papangue
Posté le 10-03-2008 à 08:42:04  profilanswer
 

par contre le code que j'ai soumis ci-dessus ne fonctionne pas sous VS2005 avec les type templates:
L'opérateur de flux sortant << est codé comme il se doit, mais est template:

Code :
  1. template<class T>
  2. std::ostream& operator<<(std::ostream& stream, const std::vector<T>& value)
  3. {
  4.        // des chose à faire
  5.        return stream;
  6. }


 
mais ce qui est bizarre c'est que
test<std::vector<double> >
me retourne que la fonction n'est pas trouvée.
 
Et là j'ai du mal à saisir la blague... Bref c'est pas totalement gagné pour le moment.
 
Pour contourner le probleme je n'ai pas le choix pour le moment de spécifier des tests supplémentaire pour les vectors avec par exemple:

Code :
  1. template <class T, std::basic_ostream<char>& (*)(std::basic_ostream<char>&,const std::vector<T>& ) >
  2. struct TestNonStatic_operator_ref_const_vect { };
  3. template<class T>
  4. static Found Test_operator_ref_const_vect(TestNonStatic_operator_ref_const_vect<typename T::value_type,&operator<< >*);
  5. template<class T>
  6. static NotFound Test_operator_ref_const_vect( ... );


 
Mais c'est pas très propre.
 
Déjà si quelqu'un peu m'expliquer pourquoi ca ne marche pas, cela me permettrait peut être de corriger mes erreurs.

n°1700125
Joel F
Real men use unique_ptr
Posté le 10-03-2008 à 19:41:34  profilanswer
 

VC++ n'est pas connu pour gérer proprement ce genre d'acrobaties.
Je penche pour une mise en evidence de sa gestion foireuse des spécialisations de templates :/ Rien à faire ...

n°1700206
papangue
Posté le 10-03-2008 à 21:51:42  profilanswer
 

Joel F a écrit :

VC++ n'est pas connu pour gérer proprement ce genre d'acrobaties.
Je penche pour une mise en evidence de sa gestion foireuse des spécialisations de templates :/ Rien à faire ...


 
Merci pour ta réponse. Ceci explique les abbérations de fonctionnement que je retrouve à travers les tests que j'effectuent sous VC++.
 
Bien cordialement,

n°1700209
Joel F
Real men use unique_ptr
Posté le 10-03-2008 à 21:56:21  profilanswer
 

perso, j'ai arrêté Visual et la méta-prog. Y a toujours un cas foireux qui pète au détour d'un cas particulier. Sans compter que VC++ (enfin WC++) ne supporte que partiellement l'ADL et autre truc complètement indispensable.


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

  Metaprogrammation: Comment détecter si une fonction existe ou pas

 

Sujets relatifs
Debug d'une fonction de validationEXISTE T IL UNE VERSION DE TURBO PASCAL ?
Créer une fonction en VBA[Résolu] Problème de variable qui veut pas sortir d'une fonction.
Probleme avec la fonction mysql_connectsynchronized processes : ça existe?
[MySQL] Requète aléatoire en fonction du jourComment faire un fichier de fonction
fonction GENERIQUE pour afficher/cacher des DIV[Access] Filtrer liste déroulante en fonction d'une autre
Plus de sujets relatifs à : Metaprogrammation: Comment détecter si une fonction existe ou pas


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