stl set sortieren nach objekt-attribut?



  • Hallo!
    Ich würde gerne ein (stl) set bestehend aus objekten verwalten.
    da set einen default-sortieren hat, muss ich ihm ja sagen, wonach er sortieren
    soll.
    erste Frage: kann ich den default-sortieren irgendwie ausschalten?
    wenn nein, dann
    zweite Frage: mein Objekt hat ein attribut, nach welchem ich ja sortieren könnte.
    nur ist mir der aufruf nicht klar.
    wenn ich das so mache:

    set<objekt, objekt.merkmal> bla
    

    meckert er.
    habt ihr da Rat?????
    Wäre super 👍
    Danke!

    Gruß
    chefzieher



  • Hallo,

    Dafür gibt es so genannte Prädikate. Prädikate sind Funktionsobjekte die für solche Augraben übergeben werden. Sie überladen den ()-operator und werden dann von den entsprechenden Containern genutzt. Als default einstellung benutzt std::set das Prädikat std::less<class Key>, sprich den Kleiner-Vergleich. Wenn du also den Operator < für deine Objecte überladen kannst, brauchst du kein Prädikat angeben.

    Ein prädikat ist efektiv eine struct oder eine Klasse die wie gesagt den ()-operator überläd.

    struct MyCompare{
         bool operator()(const &Object o,const Object &o2){return o.Attribut < o2.Attribut;}
    }
    
    //dann dein set
    std::set<Object,MyCompare> myset;
    //code....
    


  • Danke!
    Das klappt soweit ja wunderbar.
    Kann jetzt sehr schön Element einfügen.
    Allerdings scheint er bei anderen Operationen auf
    dem Set (bsp. count() oder find()) standartmäßig auf
    den std::less<class key> zuzugreifen.
    das will ich aber nicht, da ja sonst nur murks rauskommt.
    wie kann ich diese methode überladen? oder habt ihr ne andere
    idee???
    danke!



  • du musst den kleiner operator überladen

    bool operator<(Objekt& a,Objekt& b){
    return a.getvalue()<b.getvalue();//oder so ähnlich 😃
    }



  • Hmm,

    normalerweise sollte er für find() auch das Prädikat benutzen. Wie kommst du denn zu dem Schluss ?



  • prolog schrieb:

    Hmm,

    normalerweise sollte er für find() auch das Prädikat benutzen. Wie kommst du denn zu dem Schluss ?

    Naja, die Fehlermeldung bei "find()" und auch bei "count()" verweist auf
    die set-operation "Lbound" und spezieller auf diesen Bereich:

    if (key_compare(_Key(_X), _Kv))
                                    _X = _Right(_X);
                            else
                                    _Y = _X, _X = _Left(_X);
    

    und das sagt mir, dass der gute einen Vergleich anstellen will, er aber nicht genau weiß, wie er das tun soll.
    Wie kann ich ihm also helfen???



  • Hallo,

    also key_compare ist eine typedef deines Prädikates. Also benutzt der schon das Prädikat. Kannst du evtl. mal etwas beispielcode posten und auch dein Prädikat. hier kann ich im moment nicht erkennen was da falsch laufen sollte.



  • Vielleicht hilft es ja schon, den operator() deines Prädikats als 'const' zu markieren. Wenn nicht, ist es trotzdem sauberer und üblicher 🙂


Anmelden zum Antworten