boost::bind, pourquoi this ne marche pas?

boost::bind, pourquoi this ne marche pas? - C++ - Programmation

Marsh Posté le 27-09-2006 à 12:26:08    

Bonjour,
 
j'ai une question au regard de l'utilisation de boost::bind et de la librairie de functor également présente i.e. boost::function. En gros j'utilise bind afin d'envoyer après création d'un objet une fonction libre de type double(double,double) a une grille de calcul génerique qui fonctionne uniquement avec des fonctions libres. Le soucis est que je désire écrire du code un peu générique et j'utilise le polymorphisme pour les objets créés. J'ai le code suivant:

Code :
  1. template<Rule1=default,Rule2=default>
  2. class A
  3. {
  4. public:
  5.     A(){}
  6.     A(double param1) : m_param1(param1){}
  7.     virtual double evaluate(double x,double y){return x*m_param1+y;}
  8.     virtual boost::function<double(double,double)> getFunctor()
  9.     {return boost::function<double(double,double)>(boost::bind(evaluate,this,_1,_2));}
  10.     virtual void(Grid* grid) sendfunction() {grid->sendFunction(getFunctor());}
  11. protected:
  12.     double m_param1;
  13. }
  14. class B : virtual public A<default,default>
  15. {
  16. public:
  17.     B():A<default,default>(){}
  18.     B(double param1,double param2=0.) : A<default,default>(param1),m_param2(param2){}
  19.     virtual double evaluate(double x, double y){return x*m_param1+y*m_param2;}
  20. private:
  21.     double m_param2;
  22. }
  23. int main()
  24. {....}


 
Maintenant mon(mes) problème(s). Ce code compile sans soucis ni warning (VS 7.1 je crois). Toutefois l'éxecution au moment de l'appel du functor dans la grid de calcul, c'est n'importe quoi et dans la grande tradition de bind de boost, il est impossible de savoir ce qu'il se passe. Donc j'ai changer le code de getFunctor() pour:

Code :
  1. boost::bind(evaluate,(*this),_1,_2)


... et tout rentre dans l'ordre le binding est éxecuté sans problème et son éxécution sans soucis. Toutefois le polymorphisme est détruit dans la mesure où la fonction evaluate() bien que virtual est éxécuté à partir du this présent dans la classe A et donc va chercher la fonction evaluate de base.
Donc:
1- Pourquoi l'instanciation par pointer de boost::bind déconne (pour parler poliment) alors que la doc (par ex le livre de Karlsson) précise qu'il peut utiliser indiféremment objet, pointer, smart pointer etc...
2-Existe-t-il un moyen de garder le polymorphisme de evaluate tout en évitant de recopier la function getFunctor(). Est-ce que définir evaluate() en pure virtual (=0) fonctionnerait?
 
Merci d'avance.


Message édité par ElDesdichado le 27-09-2006 à 14:43:48
Reply

Marsh Posté le 27-09-2006 à 12:26:08   

Reply

Marsh Posté le 27-09-2006 à 13:08:54    

Ca ne peut pas marcher:
- m_param1 est private
- je ne vois pas comment bind pourrait utiliser une pointeur de fonction membre virtuelle comme tu l'entends.¨
 
J'ai l'impression que tu vas cumuler les inconvénients des templates (debug, mise au point) et du polymorphisme (perfs)

Reply

Marsh Posté le 27-09-2006 à 13:25:28    

- J'ai édité le post (private est en fait proteced dans mon code).
- En fait bind marche parfaitement dans le deuxième contexte bien que je sois obligé de réécrire la fonction getFunctor(). Je pense que si je défini evaluate comme pure virtual je pourrais éviter cet inconvénient, forcant par la même le compilateur à descendre dans les classes(menfin je suis pessimiste). De manière général bind ne pose pas de problème avec les fonctions virtuelles, mais renvoie un pointer sur un membre non static (qui n'est donc pas réllement un pointer). Enfin quoiqu'il en soit ce code fonctionne et au sujet des perfs, toute l'architecture créé le minimum d'objet à l'initialisation et ensuite renvoie des fonctions "binded" libres au moteur de calcul qui donc travaille sur aucune fonctions virtuelles ou appels d'objets. Basiquement c'est un moteur pour résolution a base de différences finies qui sur des problèmes de l'ordre de 300*9000 rend des résultats en moins de 5s sur IBM IntelliStation Z Pro Biproc.

Reply

Marsh Posté le 27-09-2006 à 14:13:37    

Avec MSVC8.0 ça semble fonctionner en écrivant "boost::bind(&A::evaluate,this,_1,_2));}". Sinon ça compile pas.

Reply

Marsh Posté le 27-09-2006 à 14:49:24    

verdoux a écrit :

Avec MSVC8.0 ça semble fonctionner en écrivant "boost::bind(&A::evaluate,this,_1,_2));}". Sinon ça compile pas.


 
 :sweat: Effectivement comme tu as du le remarquer je n'ai publier ce code que pour illustrer mon pb. Je ne vais pas balancer des classes de plusieurs page sur le forum (désolé de t'avoir fait perdre ton temps). Il manque plein de trucs et il y des erreurs dans le code (par exemple j'ai édité le post pour corriger B():A<default,default>(){} etc... il faut définir default etc...). En tout cas merci je vais enquêter un peu plus pouvoir si je peux le faire fonctionner avec this et &A::evaluate. De manière générale ne travaillant pas avec la dernière version de boost je me demande si il n'y a pas eu des améiliorations entre temps (en fait sûrement). Merci bien pour les suggestions en tout cas!


Message édité par ElDesdichado le 27-09-2006 à 14:49:59
Reply

Marsh Posté le 27-09-2006 à 19:59:50    

t'as qu'à commencer à utiliser autre chose que des mots-clefs comme identifiants sur ton compilo vaseux, on verra ensuite.


Message édité par Taz le 27-09-2006 à 20:00:03
Reply

Marsh Posté le 28-09-2006 à 08:34:57    

j'apprécierai que tu ne reste en dehors de ce thread (au regards de tes posts sur d'autres topics, il est clair que tu n'as en aucun cas les connaissances pour répondre/participer). J'aimerai éviter le bruit sur ma question. Si tu lis les posts précédents tu verras que je n'ai absolument pas écrit le code que j'utilise mais un exemple quick and dirty pour illustrer mon problème.
 
En te remerciant de ne pas participer à mes threads à l'avenir...

Reply

Marsh Posté le 28-09-2006 à 08:40:21    

définir la fonction evaluate en pure virtual ne fonctionne pas... pour ceux que ca intéresse.

Reply

Marsh Posté le 28-09-2006 à 10:12:21    

bah comment veux-tu qu'on travaille avec du code pas compilable, pas fonctionnel dès la première ligne...

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed