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

  FORUM HardWare.fr
  Programmation
  C++

  [RESOLU] probleme avec le lower_bound d'un vector de classes

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[RESOLU] probleme avec le lower_bound d'un vector de classes

n°1320131
sebchap
Share the knowledge
Posté le 07-03-2006 à 13:18:33  profilanswer
 

Bonjour :hello: ,
Voila le contexte de mon probleme:
J'ai une classe Agence et une autre Annonce. La classe Agence contient theoriquement un tableau d'Annonces (vector<Annonce> _tab), mais j'ai preféré utiliser un vector d'Annonce pour plus de souplesse :)
La classe Annonce est caractérisé par plusieurs données dont un loyer (int _loyer). On veut faire un classement des Annonces contenues dans l'Agence par montant de loyer croissant.
J'ai donc redéfini l'operator< comme suit:

Code :
  1. bool Annonce::operator<(const Annonce& a) const
  2. { return(_loyer<a._loyer);}


 
Lors de la construction d'une Agence, un certain nombre d'Annonces sont ajoutées au vector. Ce que j'ai deja fait, c'est: construire l'Agence avec des Annonces et trier au final le vector avec sort(_tab.begin(), _tab.end())
Ce que je voudrais faire, c'est une methode de la classe Agence pour ajouter une annonce en conservant le tri. J'ai la possibilité d'ajouter l'annonce à la fin du vector (push_back) puis de re-trier le vector, mais ca ne me parait pas très optimisé :/ Au lieu de ca, j'ai pensé utiliser la methode insert des vector avec comme iterateur, celui renvoyé par la methode lower_bound. A priori, c'est exactement ce qu'il me faut, mais evidemment, j'ai des problemes :D
La fonction sort marche sans probleme et utilise bien mon operator< pour effectuer le tri, mais lower_bound n'a pas l'air d'y arriver :(
Concretement, voici la fonction que j'utilise:

Code :
  1. void Agence::ajout(const Annonce& a)
  2. {
  3.   int new_loyer, .... //autres données qui serviront a construire l'annonce
  4.   vector<Annonce>::iterator ma_place //ma_place stockera la valeur de retour de lower_bound
  5.   ... //saisie des données de l'annonce
  6.   cin >> new_loyer;
  7.   ma_place=lower_bound(_tab.begin(), _tab.end(), new_loyer);  //je recherche l'endroit où placer ma nouvelle annonce en conservant le tri par loyer
  8.   _tab.insert(ma_place, Annonce(..., new_loyer, ...));  //insertion de la nouvelle annonce en appelant le constructeur de cette classe
  9. ...
  10. }


Et là, c'est le drame :D A la compilation, il me renvoi une erreur sur l'appelle de lower_bound. Je n'ai pas le message précis sous les yeux, mais de mémoire, il me dit "no match for" la fonction de comparaison utiliser par lower_bound tout en le disant qu'un candidat possible est mon operator< de ma classe Annonce. Ce que je ne comprend pas, c'est pourquoi il n'aime pas mon operateur, alors que la fonction sort s'en contente très bien :??:
 
J'ai vu dans pas mal d'exemple d'utilisation de lower_bound qu'on declarait un typedef vector<machin>::iterator BIDULE mais ca ne m'a pas sembler necessaire de le faire et je ne pense pas que l'erreur vienne de là. J'ai aussi essayé de creer une autre fonction de comparaison, mais comme ca parlait de pointeur de fonction toussa² (truc que je ne gère absolument pas) le resultat a été desastreux [:petrus75]
 
J'avoue que je suis un peu perdu, donc votre aide est la bienvenue :)
Merci :jap:
 
P.S: j'utilise g++ 4 si ca peut influencer :D


Message édité par sebchap le 10-03-2006 à 23:42:48

---------------
BOFH excuse #400:We are Microsoft.  What you are experiencing is not a problem; it is an undocumented feature.
mood
Publicité
Posté le 07-03-2006 à 13:18:33  profilanswer
 

n°1320133
skelter
Posté le 07-03-2006 à 13:26:36  profilanswer
 

si tu veux faire du tri par insertion un std::set (ou std::multiset) conviendra mieux je penses


Message édité par skelter le 07-03-2006 à 13:26:49
n°1320144
sebchap
Share the knowledge
Posté le 07-03-2006 à 13:44:52  profilanswer
 

Je vais essayer avec std::set. (ca fait une notion de plus a comprendre :sweat: )
Mais comme je suis curieux, j'aimerais savoir qu'est ce qui cloche avec lower_bound :D D'ailleurs, std::set utilise aussi une fonction de comparaison d'après ce que j'ai vu, donc le probleme risque de persister (mais bon, je serais fixé lorsque j'essaierais ;) ).


---------------
BOFH excuse #400:We are Microsoft.  What you are experiencing is not a problem; it is an undocumented feature.
n°1320321
LePhasme
Les Belges domineront le monde
Posté le 07-03-2006 à 16:47:24  profilanswer
 

C'est possible que tu nous copies/colles ton code et le message d'erreur complet ?
Et ton _tab il est de quel type ?


Message édité par LePhasme le 07-03-2006 à 16:53:26
n°1320907
sebchap
Share the knowledge
Posté le 08-03-2006 à 14:04:47  profilanswer
 

_tab est un vector d'Annonce et la classe Annonce est defini comme ca (et je met la classe Agence au passage aussi :D ):

Code :
  1. class Annonce{
  2.   private:
  3. int _num, _nbpiece, _surf, _loyer, _charges;
  4. string _type;
  5.   public:
  6. Annonce();
  7. Annonce(int, string, int, int, int, int); //remplit l'annonce avec les paramètres
  8. void afficher();
  9. int retourneElt(string);    //retourne un des membres privé
  10. string typeAnnonce() {return(_type);}
  11. bool operator<(const Annonce& a) const
  12.  {return(_loyer<a._loyer);} //definition de la comparaison pour l'algorithme sort
  13. };
  14. class Agence{
  15.   private:
  16. vector<Annonce> _tab;
  17. int _nbAnnonces;
  18.   public:
  19. Agence(int);
  20. ~Agence() {_tab.clear();}
  21. void ajout(int);
  22. void ajout(Annonce);
  23. void afficher();
  24. int compteType(string);
  25. Annonce& chercheAnnonce(string, int);
  26. int chercheAnnonce(int*, int, int);
  27. };


Et maintenant, la fonction qui pose probleme:

Code :
  1. void Agence::ajout(int mode)
  2. {
  3.   static int numero=0; //permet d'eviter des annonces ayant le même numero
  4.   int nbpiece, surf, loyer, charges;
  5.   string type;
  6.   vector<Annonce>::iterator place;
  7.   numero++;
  8.   if (mode) //saisie aléatoire
  9.   {
  10. type=(!int(double(rand())/RAND_MAX*2)) ? "appartement" : "maison"; //apartement (0) ou maison (1)
  11. nbpiece=int(double(rand())/RAND_MAX*10+1);  //entre 1 et 10 pièces
  12. surf=int(double(rand())/RAND_MAX*100+9);  //entre 9 et 108m²
  13. loyer=int(double(rand())/RAND_MAX*1000+100); //entre 100 et 1099¤
  14. charges=int(double(rand())/RAND_MAX*500);  //entre 0 et 499¤*/
  15. place=lower_bound(_tab.begin(), _tab.end(), loyer);   // <-- fonction qui pose probleme
  16. _tab.insert(place, Annonce(numero, type, nbpiece, surf, loyer, charges));
  17.   }
  18.   else {........} //saisie manuelle, ca fait la même chose
  19.   _nbAnnonces=_tab.size();
  20. }


Et donc l'erreur en question (normalement je compile sous Linux, mais là je n'ai qu'un poste windows mais l'erreur est la même de memoire :) ) :

C:/Program Files/Dev-Cpp/include/c++/3.3.1/bits/stl_algo.h: In function `
   _ForwardIter std::lower_bound(_ForwardIter, _ForwardIter, const _Tp& ) [with  
   _ForwardIter = __gnu_cxx::__normal_iterator<Annonce*, std::vector<Annonce,  
   std::allocator<Annonce> > >, _Tp = int]':
F:/miniprojets/mini-projet_4/4/agence.C:28:   instantiated from here
 
C:/Program Files/Dev-Cpp/include/c++/3.3.1/bits/stl_algo.h:2792: error: no  
   match for 'operator<' in '
   (&__middle)->__gnu_cxx::__normal_iterator<_Iterator,  
   _Container>::operator*() const [with _Iterator = Annonce*, _Container =  
   std::vector<Annonce, std::allocator<Annonce> >]() < __val'
F:/miniprojets/mini-projet_4/4/annonce.h:17: error: candidates are: bool  
   Annonce::operator<(const Annonce& ) const


Le genre d'erreur que j'aime pas [:petrus75]
 
Merci de votre aide :jap: (j'avoue j'ai pas encore essayé avec std::set, j'ai pas trop le temps en ce moment, dsl)


---------------
BOFH excuse #400:We are Microsoft.  What you are experiencing is not a problem; it is an undocumented feature.
n°1320923
Taz
bisounours-codeur
Posté le 08-03-2006 à 14:24:39  profilanswer
 

t'es bien gentil de comparer des Annonce et des int ...

n°1323083
sebchap
Share the knowledge
Posté le 10-03-2006 à 21:14:07  profilanswer
 

Je pensais que la re-définition de l'operateur < pouvait regler le probleme. Tu penses donc que je ne peux pas m'en sortir avec lower_bound et une classe ? Je debute un peu avec les templates et les conteneurs, donc toute aide est la bienvenue :jap:

n°1323084
Taz
bisounours-codeur
Posté le 10-03-2006 à 21:15:22  profilanswer
 

mais bon sang, comme tu fais pour comparer
 
 
3 < petite_annonce ?

n°1323097
sebchap
Share the knowledge
Posté le 10-03-2006 à 21:59:05  profilanswer
 

Merci beaucoup :love: Même si ta facon de me le faire remarqué n'est pas très douce, j'ai au moins compris mon erreur :jap:
J'ai donc redefini mon operateur pour la comparaison avec des int (d'un coté comme de l'autre).
Merci aussi à skelter pour on idée qui me resservira sans doute plus tard ;)

n°1323106
Taz
bisounours-codeur
Posté le 10-03-2006 à 22:15:35  profilanswer
 

NON ! NON ! NON !
 
il te faut soit :
 
Annonce::Annonce(int);
 
soit :
 
Annonce::operator int() const

mood
Publicité
Posté le 10-03-2006 à 22:15:35  profilanswer
 

n°1323114
sebchap
Share the knowledge
Posté le 10-03-2006 à 22:33:22  profilanswer
 

Euh, là j'avou ne pas comprendre :??: La redefinition de l'operateur marche très bien et me semble être une facon "propre" de coder, non ?
Il faudrait que tu explique un peu plus ce que tu as en tete ;) Si je comprend bien la deuxieme solution, tu me demande de definir un operateur de cast alors que ma classe Annonce ne s'y prete pas tout à fait (donc je dois surement être à cent lieues de ce que tu pense)
et pour la premiere solution, je ne la comprend pas l'interet de ce nouveau constructeur :??:
Donc donne moi plus d'explications stp :jap:

n°1323120
Taz
bisounours-codeur
Posté le 10-03-2006 à 22:41:12  profilanswer
 

non c'est dégueux et pas pas orthogonal du tout.
 
montre ta surcharge bidon d'operator<(Annonce, int) et je te dis quoi faire.

n°1323125
++fab
victime du syndrome IH
Posté le 10-03-2006 à 22:46:43  profilanswer
 

Taz a écrit :

il te faut soit :
Annonce::Annonce(int);


avec un acces *private*
 
Et définir  
bool operator<( Annonce const& lhs, Annonce const& rhs)
{
    return lhs.loyer < rhs.loyer;
}
 

Citation :

soit :
Annonce::operator int() const


Je vois pas l'utilité la ...
 

n°1323126
sebchap
Share the knowledge
Posté le 10-03-2006 à 22:46:59  profilanswer
 

Code :
  1. bool operator<(int i) const
  2.    {return(_loyer<i);}


Hop là, j'ai rajouté ca dans la definition de ma classe Annonce. Apparemment, même pas besoin d'en definir un exterieur a la classe pour la comparaison de int<Annonce.
 
edit: grilled :D je vais regarder tout ca :)


Message édité par sebchap le 10-03-2006 à 22:47:56
n°1323128
++fab
victime du syndrome IH
Posté le 10-03-2006 à 22:48:04  profilanswer
 

sebchap a écrit :

Euh, là j'avou ne pas comprendre :??: La redefinition de l'operateur marche très bien et me semble être une facon "propre" de coder, non ?


euh... Non !

n°1323131
skelter
Posté le 10-03-2006 à 22:50:59  profilanswer
 

non, comme ils t'ont dis en dehors de la classe pour pouvoir faire
int < annonce ou
annonce < int
+ le constructeur qui permet au compilateur de construire annonce à partir de int

n°1323135
sebchap
Share the knowledge
Posté le 10-03-2006 à 22:53:36  profilanswer
 

++fab a écrit :

euh... Non !


Ah d'accord, c'est toujours ca de pris :D Il y a une raison a ca ?
 
Sinon j'ai toujours pas compris le Annonce::Annonce(int) :/
Quel est l'avantage de l'operateur bool operator<( Annonce const& lhs, Annonce const& rhs) par rapport a celui que j'ai defini dans la classe ?
 
edit: et encore grillé, mais cette fois j'ai compris :jap: En plus, j'avais deja etudier le cas du constructeur :D

Message cité 1 fois
Message édité par sebchap le 10-03-2006 à 22:54:58
n°1323137
++fab
victime du syndrome IH
Posté le 10-03-2006 à 23:01:39  profilanswer
 

sebchap a écrit :

Ah d'accord, c'est toujours ca de pris :D Il y a une raison a ca ?


Il n'y a pas de raisons formelles, mais tu sens bien que dans ton cas, comparer un int à une annonce, c'est totalement artificiel.
Une annonce, ça se compare à une annonce. Et comment on compare deux annonces ? à toi de voir ... Si c'est en fonction du loyer, et bien tu le défini en fonction.
 

Citation :

Quel est l'avantage de l'operateur bool operator<( Annonce const& lhs, Annonce const& rhs) par rapport a celui que j'ai defini dans la classe ?

Il compare 2 annonces.

n°1323141
Taz
bisounours-codeur
Posté le 10-03-2006 à 23:16:48  profilanswer
 

Annonce::Annonce(int l) : _loyer(i) { }
 
 
et voilà.

n°1323150
sebchap
Share the knowledge
Posté le 10-03-2006 à 23:42:10  profilanswer
 

Merci beaucoup a vous tous :jap: Ca marche au poil et j'ai compris ce que je faisais :D


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

  [RESOLU] probleme avec le lower_bound d'un vector de classes

 

Sujets relatifs
[Resolu][Vérification de doublon dans la BDD[Batch File] Problème d'espace
Error variable + cours sur les classes.problème de condition et de timing du coup...
[PERL] Problème avec tableaux / liste imbiqués[PHP] Calcul avec des nb a virgules [RESOLU]
[Javascript] Problème de rafraichissement d'imageProblème d'import SQL Server 2005 (DTS)
Problème avec un LDAP_BINDProbleme de gestion du son dans flash
Plus de sujets relatifs à : [RESOLU] probleme avec le lower_bound d'un vector de classes


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