IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

MFC Discussion :

STL : std::set probl�me avec insert ...


Sujet :

MFC

Vue hybride

Message pr�c�dent Message pr�c�dent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    21
    D�tails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2003
    Messages : 21
    Par d�faut STL : std::set probl�me avec insert ...
    Bonjour,

    j'aimerais utilis� std::set, mais j'ai quelques ennuis ...


    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    // ------
    class SCImports
    {
    public:
       SCImports(const std::string & etat1, const std::string & etat2)
          : nom1(etat1),nom2(etat2)
       {
       }
       std::string nom1;
       std::string nom2;
    };
     
    // ------
    // déclaration dans une autre classe Test
    std::set<SCImports>                 listeSCImports;
     
    // ------
    // utilisation dans cette autre classe Test
     
    ((std::set<SCImports>) listeMaClasse).insert((SCImports)classe);
    Si je compile la classe Test, j'obiens de visual 2002 cette erreur :

    C:\Program Files\Microsoft Visual Studio .NET\Vc7\include\functional(139): error C2676: binary '<' : 'const SCImports' does not define this operator or a conversion to a type acceptable to the predefined operator

    d'o� ma question, est-ce que je dois surcharger l'op�rateur "<" ?
    Est-ce que �a ne devrait pas plut�t �tre l'op�rateur "==" pour d�terminer si la cl� (l'�l�ment � ins�rer) est d�j� pr�sent dans la "liste" set ?

    Si je dois surcharger l'op�rateur comment je fais avec ma classe qui a seulement 2 string en attribut, et plus int�ressant comment je fais si c'est une classe qui a plein d'attributs ?

    Merci de vos r�ponses, j'esp�re avoir �t� clair. Cependant, il se peut que je n'ai pas bien compris le fonctionnement de set (qui pour moi est une sorte de liste de cl� donc impossible d'avoir 2 fois la m�me cl� dans set), si c'est le cas merci de me donner d'autres informations...

    En passant, un lien int�ressant sur les containers :

    http://www.mines.u-nancy.fr/~tombre/...olyCpp008.html

    Big. K

  2. #2
    Membre exp�riment�
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    290
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2002
    Messages : 290
    Par d�faut
    il faut surcharger < ET == ET le constructeur de copie ET l'operateur =

  3. #3
    Membre chevronn�
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par d�faut Re: STL : std::set probl�me avec insert ...
    Citation Envoy� par Big K.
    Bonjour,
    C:\Program Files\Microsoft Visual Studio .NET\Vc7\include\functional(139): error C2676: binary '<' : 'const SCImports' does not define this operator or a conversion to a type acceptable to the predefined operator

    d'o� ma question, est-ce que je dois surcharger l'op�rateur "<" ?
    Est-ce que �a ne devrait pas plut�t �tre l'op�rateur "==" pour d�terminer si la cl� (l'�l�ment � ins�rer) est d�j� pr�sent dans la "liste" set ?
    Pour utiliser 'set' il faut disposer d'un moyen de comparer deux �l�ments.
    Il est possible de fournir une telle fonction lors de l'instanciation du template.
    Si aucune fonction de comparaison n'est fournie alors '<' est utilis� par d�faut.

    La fonction doit d�finir une relation d'ordre faible entre les �l�ments du set.
    Pour plus d'info http://www.sgi.com/tech/stl/set.html
    Le truc � retenir c'est que la comparaison doit �tre irreflexive. C-�-d que 'compare(a, a)' retourne faux. En gros, �a marche avec '<' ou '>' mais pas avec '<=' ou '>='

    Pour r�soudre le probl�me il y a alors deux fa�on de faire:
    - surcharger l'op�rateur < (pas terrible).
    - d�finir une fonction de comparaison.

    On peux, par exemple, concat�ner les deux cha�nes et de les comparer.

    Par exemple
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    struct SCImportsCompare
    {
      bool operator()(const SCImports& lhs, const SCImports& rhs) const
      {
         string s1(lhs.nom1);
         s1.append(lhs.nom2);
     
         string s2(rhs.nom1);
         s1.append(rhs.nom2);
     
         return ( s1.compare(s2) < 0 );
      }
    };
     
     
    // Création du Set
    set<SCImports, SCImportsCompare> mySet;

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    21
    D�tails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2003
    Messages : 21
    Par d�faut
    je viens de faire :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    bool operator < (const SCImports& _Right) const
    {	// apply operator< to operands
             int result = this->nom1.compare(_Right.nom1);
             if (result < 0)
                return true;
             else
                return false;
    }
    et �a compile, seulement �a r�gle pas mon probl�me, car � mon avis la cl� ne se fait que sur le nom1 !!!

    Sinon pourquoi je devrais surcharger "==", "=" et le constructeur de copie ?

  5. #5
    Membre chevronn�
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par d�faut
    Citation Envoy� par Gandalf
    il faut surcharger < ET == ET le constructeur de copie ET l'operateur =
    Je ne vois pas de raison imm�diate de d�finir '==' .

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    21
    D�tails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2003
    Messages : 21
    Par d�faut
    Merci VoidSeer, j'aime bien ton id�e de concat�ner les 2 chaines

    Sinon quand on a une grande classe, il n'y a pas de moyen miracle.
    pffou, heureusement que je n'ai que 2 strings :>

  7. #7
    Membre chevronn�
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par d�faut
    Citation Envoy� par Big K.
    Merci VoidSeer, j'aime bien ton id�e de concat�ner les 2 chaines

    Sinon quand on a une grande classe, il n'y a pas de moyen miracle.
    pffou, heureusement que je n'ai que 2 strings :>
    Je ne suis pas sur qu'utiliser un set dans le probl�me que tu essaie de r�soudre une solution adapt�e si tu as du mal � d�finir une comparaison entre eux.

    Si ce que tu souhaite c'est d'avoir une liste d'objet ou une m�me instance n'appara�t pas plus d'une fois, il serait plus facile de manipuler un set de pointeurs.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    21
    D�tails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2003
    Messages : 21
    Par d�faut
    non c juste une liste de string, rien � voir avec les instances ...

    Merci, donc en gros il suffit de faire avec une classe de comparaison et �a compile (on verra � l'ex�cution !!!), fin �a ne devrait plus me poser de probl�mes.

    Donc si jamais j'ai une grande classe, il suffit de comparer chaque attribut entre eux ?

    J'ai un doute sur la concat�nation de mes deux chaines ? Est-ce que si je fais ((lhs.nom1 == rhs.nom1) && (lhs.nom2 == rhs.nom2)) �a marche ou non ?

    D�sol�, mais chez moi c'est le matin, et je suis pas encore tr�s clair ...

  9. #9
    Membre chevronn�
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    394
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 394
    Par d�faut
    Citation Envoy� par Big K.
    non c juste une liste de string, rien � voir avec les instances ...
    J'ai un doute sur la concat�nation de mes deux chaines ? Est-ce que si je fais ((lhs.nom1 == rhs.nom1) && (lhs.nom2 == rhs.nom2)) �a marche ou non ?
    Non, c'est le point �pineux. Set ne veux pas de fonction d'�galit�, mais de comparaison.

    <mode matheux on>
    La fonction de comparaison doit avoir les trois propri�t�s suivante:
    - irreflexivit�: compare(a, a) retourne faux !
    - transitivit�: si compare(a,b) et compare (b,c) sont vrai alors compare(a,c) doit aussi �tre vrai.
    - antisymetrique: si compare(a,b) est vrai alors compare(b,a) est n�cessairement faux.

    Une relation d'�galit� est par nature r�flexive et symetrique
    (a == a) et si (a == b) alors (b == a) donc l'�galit� ne peut pas servir comme fonction de comparaison dans un set.
    <mode matheux off>

    C'est pour cela que dans mon exemple pr�c�dant j'utilise une comparaison stricte entre 0 et la comparaison des deux cha�nes de caract�res.

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    21
    D�tails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2003
    Messages : 21
    Par d�faut
    ok, merci pour cette explication, je le sentais bien que c'�tait une id�e b�te mon test d'�galit�, mais je ne voyais pas pourquoi.

    Merci encore.

  11. #11
    Membre exp�riment�
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    290
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2002
    Messages : 290
    Par d�faut
    pourquoi surcharger =, ==, et le constructeur de copie ?
    Parce que c'est, me semble-t-il, la classe cannonique...

    tu risque de recontrer des Pb tant que tu ne les aura pas surcharg�s...

    Les pires sont les constructeur de copie, et l'operateur d'affectation. Ils peuvent etre g�n�r� par le compilo au besoin ! et donc les copies peuvent etre mal faites... Si tu ne veux pas les surcharger, il est bon de les d�clarer en private et de ne pas les implementer, ainsi le compilo ne peut plus les generer, et l'utilisation implicite d'un de ces formes provoque une erreur de compil si c'est a l'exterieur de la classe, de link si c'est � l'interieur...

    Quand au == s'il n'est pas surcharg� il est alors suppos� etre :

    !((a<b)||(b<a))

    ce qui n'est pas toujours ce que l'on souhaite...

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    21
    D�tails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2003
    Messages : 21
    Par d�faut
    Bon la m�thode de VoidSeer fonctionne parfaitement.
    Sinon j'ai pu me renseigner aupr�s de quelqu'un qui maitrise le C++ et on peut �galement d�finir un op�rateur < � la classe SCImports, ensuite on doit juste d�clarer le set ainsi :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    std::set<SCImports, std::less<SCImports>>                 listeSCImports;
    et �a fonctionne aussi bien.

    Merci � tous.

  13. #13
    Expert confirm�
    Avatar de Luc Hermitte
    Homme Profil pro
    D�veloppeur informatique
    Inscrit en
    Ao�t 2003
    Messages
    5 296
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyr�n�es)

    Informations professionnelles :
    Activit� : D�veloppeur informatique
    Secteur : A�ronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Ao�t 2003
    Messages : 5 296
    Par d�faut
    Normalement, si tu d�fini l'op�rateur <, inutile de l'expliciter dans la d�claration de l'ensemble. On manipule explicitement le second param�tre, essentiellement si la fonction d'ordre utilis�e n'est pas l'op�rateur <. C'est ce que disait (implicitement) VoidSeer dans son premier message.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne r�ponds � aucune question technique par le biais de ce m�dia. Et de toutes fa�ons, ma BAL sur dvpz est pleine...

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    21
    D�tails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2003
    Messages : 21
    Par d�faut
    exact, c'est juste que c'est un peu plus lisible ...

+ R�pondre � la discussion
Cette discussion est r�solue.

Discussions similaires

  1. [Conception] Probl�me avec INSERT dans une TABLE
    Par dunbar dans le forum PHP & Base de donn�es
    R�ponses: 26
    Dernier message: 20/07/2006, 12h56
  2. Probl�me avec insertion image
    Par technopole dans le forum Tableaux - Graphiques - Images - Flottants
    R�ponses: 2
    Dernier message: 26/06/2006, 21h45
  3. [VB6] Probl�me avec insertion d'ic�nes dans menu
    Par marsup54 dans le forum VB 6 et ant�rieur
    R�ponses: 3
    Dernier message: 02/03/2006, 21h38
  4. R�ponses: 12
    Dernier message: 25/11/2005, 12h29
  5. R�ponses: 3
    Dernier message: 10/05/2005, 11h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo