Problème de compilation de programmes de tri avec portland

Problème de compilation de programmes de tri avec portland - C++ - Programmation

Marsh Posté le 28-06-2005 à 17:49:47    

Bonjour,  
 
j'ai déja posé certaines questions relatifs aux opération de tri avec la STL. Ainsi, j'étais parvenu à l'écriture de programmes de ce type, qui se rapporchait le plus du cas que je souhaitais traiter :
 

Code :
  1. #include <list>
  2. #include <iostream>
  3. using namespace std;
  4. class Article 
  5. public
  6.   Article() {} 
  7.  
  8.   double prix() const
  9.   { 
  10.     return (_prix); 
  11.   } 
  12.  
  13.   void new_prix(double _new_prix) 
  14.   {
  15.     _prix = _new_prix; 
  16.   } 
  17.  
  18. protected
  19.  
  20.   double _prix; 
  21. }; 
  22. struct Compar : greater<Article *>
  23.   bool operator()(const Article* left,const Article* right) const
  24.   { 
  25.     return (left->prix()<right->prix()); 
  26.   } 
  27. };
  28. int main()
  29. {
  30.   int i;
  31.   Article* art;
  32.   list<Article*> list_art;
  33.   list<Article*>::iterator it;
  34.   for(i=0;i<5;i++)
  35.     {
  36.       art = new Article;
  37.       art->new_prix(rand()%10);
  38.       list_art.push_back(art);
  39.     }
  40.    
  41.   for(it=list_art.begin();it!=list_art.end();it++)
  42.     {
  43.       cout << (*it)->prix() << endl;
  44.     }
  45.   list_art.sort(Compar());
  46.   cout << "##############################" << endl;
  47.  
  48.   for(it=list_art.begin();it!=list_art.end();it++)
  49.     {
  50.       cout << (*it)->prix() << endl;
  51.     }
  52. return (1);
  53. }


 
Ainsi, on créait une liste de pointeur sur des objets de type Article, affecté d'un prix. Le tri se réalise ensuite sur les prix de ces objets.
 
Avec g++, ce programme compile et fonctionne. Mais, avec le compilateur portland pgCC, j'ai ce message d'erreur :
 

Code :
  1. "main.C", line 29: error: greater is not a template
  2.   struct Compar : greater<Article *>
  3.                   ^
  4. "main.C", line 29: error: not a class or struct name
  5.   struct Compar : greater<Article *>
  6.                   ^
  7. "main.C", line 59: error: too many arguments in function call    list_art.sort(Compar());
  8.                   ^
  9. 3 errors detected in the compilation of "main.C".


 
Sauriez vous d'où vient mon problème ? Est ce que j'ai oublié un fichier à mettre en include ou une librairie ?

Reply

Marsh Posté le 28-06-2005 à 17:49:47   

Reply

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

oui, <functional>
 
 
Fais gaffe, trié les listes, c'est bof.

Reply

Marsh Posté le 28-06-2005 à 18:18:12    

Merci Taz,
 
J'ai rajouté #include<functional>
 
A quoi sert-il au  fait ?
 
J'ai ainsi réussi à faire disparaitre mes deux premiers messages mais le troisième demeure dès la compilation (too many...Compar()); ). Est ce que je suis encore passé à coté de qqch ?
 
Merci déja de cette aide !
 

Reply

Marsh Posté le 28-06-2005 à 18:27:04    

ben ta STL est mitée. Perdu.

Reply

Marsh Posté le 28-06-2005 à 18:37:17    

C'est lapidaire !
 
Je me lance dans la reprogrammation d'un algorithme de tri ?

Reply

Marsh Posté le 28-06-2005 à 18:46:45    

surtout pas. Dans ton cas, la solution est simple et c'est d'ailleurs utilisée par list<>::sort.
 

Code :
  1. namespace My
  2. {
  3.   template<typename List, typename BinaryPredicate>
  4.   void list_sort(List& list,
  5.                  const BinaryPredicate& comp = BinaryPredicate())
  6.   {
  7.     std::vector< typename List::value_type > values(list.begin(), list.end());
  8.     std::sort(values.begin(), values.end(), comp);
  9.     list = List(values.begin(), values.end());
  10.   }
  11. }

Reply

Marsh Posté le 28-06-2005 à 18:53:11    

on peut même ruser plutôt que l'affectation finale.

Code :
  1. List sorted_list(values.begin(), values.end());
  2.     list.swap(sorted_list);

Reply

Marsh Posté le 28-06-2005 à 18:53:45    

Je plaisantais (je suis trop vieux pour m'attaquer à ça !) !
 
Merci de ta solution, je la teste dès demain.
 
En fait, c'est plutot l'implémentation de la stl par le compilateur portland qui apparaissait mitée. Je n'avais aucun de ces problèmes avec gcc.
 
Merci encore !

Reply

Marsh Posté le 28-06-2005 à 19:00:22    

c'est bien ce que je dis, la stl de portland est incomplète.

Reply

Marsh Posté le 28-06-2005 à 19:06:24    

et affine un peu la portée de tes variables, parce que là, c'est très bof.
 
En fait, même pas besoin de recopie du tout
 

Code :
  1. namespace My
  2. {
  3.   template<typename List, typename BinaryPredicate>
  4.   void list_sort(List& list,
  5.                  const BinaryPredicate& comp = BinaryPredicate())
  6.   {
  7.     std::vector< typename List::value_type > values(list.begin(), list.end());
  8.     std::sort(values.begin(), values.end(), comp);
  9.     std::copy(values.begin(), values.end(), list.begin());
  10.   }
  11. }


 
c'est moins bon que la version de stl, mais c'est déjà bien :)

Reply

Marsh Posté le 28-06-2005 à 19:06:24   

Reply

Marsh Posté le 28-06-2005 à 19:09:14    

et t'as oublié <cstdlib> et <ctime> pour std::srand(std::time(0)); et std::rand()

Reply

Marsh Posté le 04-07-2005 à 15:23:32    

Salut,
 
Bon, en fait, il semble que le problème demeure. J'ai maintenant la syntaxe suivante (désolé Taz, mais je n'ai pas encore rajouté les deux include nécessaire à l'initialisation et à la génération de nombres aléatoires) :
 

Code :
  1. #include <list>
  2. #include <vector>
  3. #include <iostream>
  4. #include <functional>
  5. using namespace std;
  6. namespace My
  7. {
  8.   template<typename List, typename BinaryPredicate>
  9.     void list_sort(List& list,
  10.     const BinaryPredicate& comp = BinaryPredicate())
  11.     {
  12.       std::vector<typename List::value_type > values(list.begin(),list.end());
  13.      
  14.       std::sort(values.begin(),values.end(),comp);
  15.       std::copy(values.begin(),values.end(),list.begin());
  16.     }
  17. }
  18. class Article 
  19. {
  20. public
  21.   Article() {} 
  22.  
  23.   double prix() const
  24.   { 
  25.     return (_prix); 
  26.   } 
  27.  
  28.   void new_prix(double _new_prix) 
  29.   {
  30.     _prix = _new_prix; 
  31.   } 
  32.  
  33. protected
  34.  
  35.   double _prix; 
  36. };
  37. struct Compar : greater<Article *>
  38.   bool operator()(const Article* left,const Article* right) const
  39.   { 
  40.     return (left->prix()<right->prix()); 
  41.   } 
  42. };
  43. int main()
  44. {
  45.   int i;
  46.   Article* art;
  47.   list<Article*> list_art;
  48.   list<Article*>::iterator it;
  49.   for(i=0;i<5;i++)
  50.     {
  51.       art = new Article;
  52.       art->new_prix(rand()%10);
  53.       list_art.push_back(art);
  54.     }
  55.    
  56.   for(it=list_art.begin();it!=list_art.end();it++)
  57.     {
  58.       cout << (*it)->prix() << endl;
  59.     }
  60.   My::list_sort(list_art,Compar());
  61.   cout << "##############################" << endl;
  62.  
  63.   for(it=list_art.begin();it!=list_art.end();it++)
  64.     {
  65.       cout << (*it)->prix() << endl;
  66.     }
  67. return (1);
  68. }


 
 
Avec ce programme (en espérant que c'est ainsi que tu le corrigeais Taz), la compilation et l'éxécution marche parfaitement avec g++ mais pas avec le compilateur Portland pgCC. Dans ce cas, dès la compilation, j'ai le message d'erreur suivant :
 

Code :
  1. C++ prelinker: executing: pgCC -c main.C
  2. "main.C", line 14: error: no instance of constructor "std::vector<T,
  3.           Allocator>::vector [with T=std::list<Article *,
  4.           std::allocator<Article *>>::value_type,
  5.           Allocator=std::allocator<Article *>]" matches the argument list
  6.             argument types are: (std::list<Article *, std::allocator<Article
  7.                       *>>::iterator, std::list<Article *,
  8.                       std::allocator<Article *>>::iterator)
  9.         std::vector<typename List::value_type > values(list.begin(),list.end());
  10.                                                        ^
  11.           detected during instantiation of "void My::list_sort(List &, const
  12.                     BinaryPredicate & ) [with List=std::list<Article *,
  13.                     std::allocator<Article *>>, BinaryPredicate=Compar]"
  14. 1 error detected in the compilation of "main.C".


 
En fait, il semble que le création du vector initial pose problème. Est ce que ce problème peut se résoudre simplement ou est-il nécessaire de faire une copie dans une boucle de chaque élément de la liste list ?
 
D'autre part, Taz, est ce que cela ne pose pas de problème d'avoir appelé list une variable définie dans la fonction void list_sort ? Ne peut-il pas y avoir confusion ? Dans ce cas, est ce que le " std:: " peut seul servir à distinguer la variable " list " du conteneur " list " ?
 
Si c'est possible d'avoir ces quelques eclaircissement, d'avance merci !

Reply

Marsh Posté le 04-07-2005 à 16:50:25    

je ne sais pas, c'est toi qui a rajouté le using. Vire le. Déplace le.
 
Sinon, utilise stc::copy dans l'autre sens pour mettre les éléments dans la liste temporaire. Mais n'écris rien à la main.

Reply

Marsh Posté le 05-07-2005 à 09:01:32    

Bon, d'une part j'ai beau déplacé le using, ça ne marche pas mieux, en tout cas avec pgCC.
 
De plus, même avec g++, je ne trouve pas l'espace de nomage stc. La ligne "using namespace stc" que j'ai rajoutée n'est pas reconnue même avec ce compilateur.
 
D'autre part, je reviens sur ma question, est ce que l'utilisation d'une variable nommée "list" ne pose pas de problème dans ce genre de programmes ? Est-ce que toutes les précautions sont prises pour qu'il n'y ait pas de confusion avec le conteneur de la STL ?

Reply

Marsh Posté le 05-07-2005 à 09:29:14    

stc ?
 
non.

Reply

Marsh Posté le 05-07-2005 à 09:39:31    

C'est toujours lapidaire !
 
Tu as bien précisé d'utiliser stc::copy pour mettre les éléments dans la liste temporaire (cf ton message du 4/7/05), non ?
 
cordialement,
 
nathan

Reply

Marsh Posté le 05-07-2005 à 09:41:44    

ben oui, j'ai précisé std:: quand j'utilise quelque chose de std. Après list, c'est un identifiant comme un autre.

Reply

Marsh Posté le 05-07-2005 à 09:49:01    

Justement, tu avais plutot écrit " stc:: " que " std :: " , non ?
 
Si je comprends bien, tu a voulu dire d'utiliser std::copy (et non  stc::copy !) pour faire un copiage dans l'autre sens des éléments de la liste ? Par rapport à ta première proposition, qu'est ce que cela change ? Ca ne résoud pas le problème, non ?
 
Tant mieux si, pour mon autre question, list est également valable comme nom d'argument !

Reply

Marsh Posté le 05-07-2005 à 10:23:01    

c'est une coquille. ça ne change rien. ta stl est mitée.
 
list est valable comme tout ce que tu veux.

Reply

Marsh Posté le 05-07-2005 à 10:41:29    

Ok pour la coquille !
 
Sinon le " mitage " de ma stl est propre à pgCC pas à g++ c'est ça ? Ce que tu veux dire c'est que la version utilisée par pgCC, à la différence de celle de g++, est trop ancienne ? ou buggée ?
 
Est ce que le chargement d'une version plus récente de la STL, sur des sites du type :
 
http://www.sgi.com/tech/stl/download.html
 
pourrrais me permettre de résoudre mon problème (ie. : utiliser des opérations de tri avec le compilateur portland, comme ce que me permet de faire g++ ?).
 
Dans ce cas, je pense que revenir au première écriture de mon programme pourrait également fonctionner, non ?

Reply

Marsh Posté le 05-07-2005 à 18:04:37    

différente et incomplète.
 
si tu te trouves un STL qui fonctionne bien avec ton compilateur, oui, ton premier programme convient.
 
Je comprends pas en quoi mon exemple de solution pose problème

Reply

Marsh Posté le 06-07-2005 à 08:20:35    

Si effectivement, la syntaxe que j'ai adoptée (cf. post du 4/7) correspond bien à ce que tu m'avais indiquée, je ne comprends pas très bien moi-même le message d'erreur.
Il est possible qu'il n'y ait pas de constructeur du conteneur de type "vector" sous la forme "vector(list.begin(),list.end())" tel que tu le proposes. Apparemment, c'est déja cette construction qui pose problème.

Reply

Marsh Posté le 06-07-2005 à 10:42:34    

et bien alors comme je t'ai dit, remplace le constructeur de vector par un vector(list.size(), typename List::value_type()) + std::copy(list.begin(), list.end(), values.begin())

Reply

Marsh Posté le 06-07-2005 à 11:28:10    

Ok, j'ai enfin compris ton std::copy ! :)
 
Effectivement, après correction, le programme suivant fonctionne parfaitement avec mon compilateur portland pgCC (j'ai encore eu quelques soucis en essayant de rajouter les include <ctime> et <cstdlib> dont le compilateur pgCC ne semblaient pas vouloir - d'où leur absence ici - mais ce n'est pas mon problème dans ce travail) :
 

Code :
  1. #include <list>
  2. #include <vector>
  3. #include <iostream>
  4. #include <functional>
  5. #include <time.h>
  6. using namespace std;
  7. namespace My
  8. {
  9.   template<typename List, typename BinaryPredicate>
  10.   void list_sort(List& list,
  11.   const BinaryPredicate& comp = BinaryPredicate())
  12.   {
  13.     std::vector<typename List::value_type > values(list.size(),typename List::value_type());
  14.    
  15.     std::copy(list.begin(),list.end(),values.begin());
  16.    
  17.     std::sort(values.begin(),values.end(),comp);
  18.    
  19.     std::copy(values.begin(),values.end(),list.begin());
  20.   }
  21. }
  22. class Article 
  23. {
  24. public
  25.   Article() {} 
  26.  
  27.   double prix() const
  28.   { 
  29.     return (_prix); 
  30.   } 
  31.  
  32.   void new_prix(double _new_prix) 
  33.   {
  34.     _prix = _new_prix; 
  35.   } 
  36.  
  37. protected
  38.  
  39.   double _prix; 
  40. };
  41. struct Compar : greater<Article *>
  42.   bool operator()(const Article* left,const Article* right) const
  43.   { 
  44.     return (left->prix()<right->prix()); 
  45.   } 
  46. };
  47. int main()
  48. {
  49.   int i;
  50.   Article* art;
  51.   // liste des pointeurs sur articles
  52.  
  53.   list<Article*> list_art;
  54.   // itérateur correspondant
  55.  
  56.   list<Article*>::iterator it;
  57.   // initialisation du germe
  58.  
  59.   srand(time(0));
  60.   // nombre d'articles a placer dans list_art
  61.   const int nart = 5;
  62.  
  63.   for(i=0;i<nart;i++)
  64.     {
  65.       art = new Article;
  66.       art->new_prix(rand()%10);
  67.       list_art.push_back(art);
  68.     }
  69.    
  70.   for(it=list_art.begin();it!=list_art.end();it++)
  71.     {
  72.       cout << (*it)->prix() << endl;
  73.     }
  74.   My::list_sort(list_art,Compar());
  75.   cout << "##############################" << endl;
  76.  
  77.   for(it=list_art.begin();it!=list_art.end();it++)
  78.     {
  79.       cout << (*it)->prix() << endl;
  80.     }
  81. return (1);
  82. }


 
Encore merci de ton aide -et de ta patience ! :jap:

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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