[STL] fonction de comparaison et algos

fonction de comparaison et algos [STL] - C++ - Programmation

Marsh Posté le 07-06-2005 à 16:29:05    

je recontre un léger probleme à la compilation, qui ne me parait pas
logique (evidemment)
 
je définit quelques structures de données:
 

Code :
  1. class point {
  2. public:
  3. point(){};
  4. point(int nx,int ny) { x=nx; y=ny;}
  5. int x;
  6. int y;
  7. };
  8. typedef enum { far_, trial_, alive_ } point_type_t;
  9. class properties {
  10. public:
  11. double potential;
  12. double action;
  13. point_type_t type;
  14. };


 
je définis par ailleurs une classe fast_marching qui contient entre autres
 

Code :
  1. class fast_marching{
  2. public:
  3.     bool  comp_function(point p1, point p2)
  4. return grid[p2.x+p2.y*size_x].action < grid[p1.x+p1.y*size_x].action; }
  5. private:
  6.         properties* grid ;
  7. vector<point> trial_heap;
  8. };


 
dans une des méthodes, je veux créer mon tas
 

Code :
  1. void fast_marching::foo()
  2. {
  3.         make_heap(trial_heap.begin(),trial_heap.end(),comp_function);
  4. }


l'erreur du compilateur concerne l'argument "comp_function" dans le make heap et est la
suivante
 


cannot convert parameter 3 from 'bool (class point,class point)' to 'bool (__thiscall *)(class point,class point)'


 
compilo VC++ 6.0, testerai sous gcc ce soir.
 
il me semble pourtant avoir défini la fonction de comparaison de la
même manière que la doc le fait.
 
Avez-vous une idée sur la question ?


Message édité par farib le 07-06-2005 à 16:29:47

---------------
Bitcoin, Magical Thinking, and Political Ideology
Reply

Marsh Posté le 07-06-2005 à 16:29:05   

Reply

Marsh Posté le 07-06-2005 à 17:28:26    

hum, solution 'partielle' au probleme, declarer la fonction static, mais du coup, la comparaison n'a plus le droit d'acceder aux membres... et n'est donc plus utile... Taz, if tu passes par la...


---------------
Bitcoin, Magical Thinking, and Political Ideology
Reply

Marsh Posté le 07-06-2005 à 17:58:04    

Je me rappele de problèmes similaires, sous linux et gcc, rencontrés également lorsque je cherchais à passer une méthode en argument d'une autre méthode. J'avais adoptée la solution donnée ici par farib, en passant la méthode en static.
 
Une solution (très très très sale) que j'avais du adoptée (mais c'était sans doute un cas plus simple) était de passer également grid en argument static ! Dans ce cas, ça doit compiler.  
 
Ainsi, avant chaque appel à make_heap, il te faudrait également t'arranger pour que l'argument static grid prenne la valeur souhaitée (et peut être le changer alors très souvent dans ton code !).

Reply

Marsh Posté le 07-06-2005 à 17:58:51    

l'argument => le membre private  
 
voulais-je dire !

Reply

Marsh Posté le 07-06-2005 à 18:10:17    

bon, en fait je pense que je n'avais pas le choix, et j'ai gruike :
 

Code :
  1. class properties {
  2. public:
  3. double potential;
  4. double action;
  5. point_type_t type;
  6. };
  7. class point {
  8. public:
  9. point(){};
  10. point(int nx,int ny,properties* p ) { x=nx; y=ny;prop=p;}
  11. int x;
  12. int y;
  13. properties* prop; //pointeur direct vers la case du tableau
  14. };
  15. bool comp_function(point p1,point p2)
  16. {
  17. return p2.prop->action < p1.prop->action;
  18. }


 
il s'agissait d'avoir un tas qui contienne une comme donnees des coordonnes de points, et construise le tas en fonction du potentiel f(x,y) du point. la je gruike, je fais pointer sur ce potentiel.


---------------
Bitcoin, Magical Thinking, and Political Ideology
Reply

Marsh Posté le 17-06-2005 à 22:06:59    

rhoo le massacre
/me fuit

Reply

Marsh Posté le 18-06-2005 à 23:47:32    

vazy, explique le massacre.


---------------
Bitcoin, Magical Thinking, and Political Ideology
Reply

Marsh Posté le 19-06-2005 à 00:05:53    

Code :
  1. #include <vector>
  2. #include <algorithm>
  3. namespace Farib
  4. {
  5.   struct Point
  6.   {
  7.     enum Type
  8.       {
  9. Far,
  10. Trial,
  11. Alive
  12.       };
  13.     int x;
  14.     int y;
  15.     Point(int nx, int ny)
  16.       : x(nx), y(ny)
  17.     { }
  18.     Point()
  19.     { }
  20.   };
  21.   struct Properties
  22.   {
  23.     double potential;
  24.     double action;
  25.     Point::Type type;
  26.   };
  27.   class FastMarching
  28.   {
  29.     std::vector<Properties> grid;
  30.     std::vector<Point> trial_heap;
  31.     size_t size_x;
  32.   public:
  33.     bool operator()(const Point& p1, const Point& p2) const
  34.     {
  35.       const double p1action = this->grid[p1.x+p1.y*this->size_x].action;
  36.       const double p2action = this->grid[p2.x+p2.y*this->size_x].action;
  37.       return p1action < p2action;
  38.     }
  39.     void foo()
  40.     {
  41.       std::make_heap(this->trial_heap.begin(), this->trial_heap.end(),
  42.       *this);
  43.     }
  44.   };
  45. }
  46. int main()
  47. {
  48.   Farib::FastMarching fm;
  49.   fm.foo();
  50. }


 
par exemple

Reply

Marsh Posté le 19-06-2005 à 00:37:49    

t'es trop fort  :sweat:  
 
je te cache pas que j'avais utilisée ma solution *gruik* comme précisé, parce que je n'avais la propre.


---------------
Bitcoin, Magical Thinking, and Political Ideology
Reply

Marsh Posté le 19-06-2005 à 00:44:23    

Plus généralement, tu peux utiliser une classe pour t'aider. Si tu ne veux pas exposer ton operator() ou bien si tu dois utiliser plusieurs stratégies
 

Code :
  1. class FastMarching
  2.   {
  3.     std::vector<Properties> grid;
  4.     std::vector<Point> trial_heap;
  5.     size_t size_x;
  6.     struct Comparator
  7.     {
  8.       FastMarching *fm;
  9.       Comparator(FastMarching *ffm)
  10. : fm(ffm)
  11.       { }
  12.       bool operator()(const Point& p1, const Point& p2) const
  13.       {
  14. const double p1action = this->fm->grid[p1.x+p1.y*this->fm->size_x].action;
  15. const double p2action = this->fm->grid[p2.x+p2.y*this->fm->size_x].action;
  16. return p1action < p2action;
  17.       }
  18.     };
  19.   public:
  20.     void foo()
  21.     {
  22.       std::make_heap(this->trial_heap.begin(), this->trial_heap.end(),
  23.       Comparator(this));
  24.     }
  25.   };

Reply

Marsh Posté le 19-06-2005 à 00:44:23   

Reply

Marsh Posté le 19-06-2005 à 00:46:13    

fm peut être const d'ailleurs. Tu peux aussi utiliser une référence

Reply

Marsh Posté le 19-06-2005 à 01:16:29    

tu ferais bien de regarder les multi_array de boost : c'st vachement bien foutu et implémenté

Reply

Marsh Posté le 20-06-2005 à 08:26:14    

tant que je suis à me cultiver:
le namespace, c'est pour encapsuler et que ce soit plus propre ?
le struc au lieu de class, c'est parce que class est pas nécessaire ?
l'utilisation de this souvent, c'est pour éviter les ambiguités de résolutions ?


---------------
Bitcoin, Magical Thinking, and Political Ideology
Reply

Marsh Posté le 20-06-2005 à 09:31:48    

1) pour éviter les collisions de noms. En C y a pas de namespace, donc on préfixe : genre gtk_label_new, gtk_box_pack_start
2) struct c'est comme classe sauf que la visibilité des membres est public et que le mode d'héritage par défaut est public.
3) oui, prend l'habitude.

Reply

Marsh Posté le 20-06-2005 à 10:37:43    

en résolvant tranquillement mes gruikeries dans l'ordre:
 
reprenons le premier post:
comment faire compiler ça ?
 
 
finalement; c'est pas tant différent de ce que tu proposais, seulement j'ai gruiké parce que je n'arrivais pas à faire avaler ça au compilo


Message édité par farib le 20-06-2005 à 10:41:01

---------------
Bitcoin, Magical Thinking, and Political Ideology
Reply

Marsh Posté le 20-06-2005 à 10:56:53    

ben si c'est différent. Comme tu avais pas saisi le concept d'objet fonction, tu mémoriser dans chaque point un pointeur vers FastMarching.
 
Le mieux, c'est la solution avec le comparateur. Comme ça tu n'a pas à exposer FastMarching::operator()

Reply

Marsh Posté le 20-06-2005 à 13:32:54    

en fait, la fonction de comparation, si elle n'est pas statique, doit OBLIGATOIREMENT être un operator() d'une classe ?


---------------
Bitcoin, Magical Thinking, and Political Ideology
Reply

Marsh Posté le 21-06-2005 à 13:13:14    

eupe : pourquoi le code proposé dans le premier post compile pas ?


---------------
Bitcoin, Magical Thinking, and Political Ideology
Reply

Marsh Posté le 21-06-2005 à 13:43:36    

farib a écrit :

en fait, la fonction de comparation, si elle n'est pas statique, doit OBLIGATOIREMENT être un operator() d'une classe ?

non. Elle doit être du type template spécifié en paramètre, tel que T t = T();  t(a, b); soit valide

Reply

Marsh Posté le 21-06-2005 à 14:33:31    

mais c'est pas logique la raison pour laquelle il me refuse de compiler
 
quand comp_function est déclarée dans la classe, ça veut pas compiler, quand ça l'est en dehors, ça passe.


---------------
Bitcoin, Magical Thinking, and Political Ideology
Reply

Marsh Posté le 21-06-2005 à 14:55:40    

ben TaClasse::comp_function(a, b) n'est pas valide.

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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