Assoziatives problem



  • Wie wäre es, wenn er als 3. Templateargument einen Dummy-Functor übergibt:

    struct dummy
    {
    int operator()
    {
    return 0;
    }
    }
    std::map<string, int, dummy> bla;
    

    Damit sollte die Sortierung doch überschrieben werden und durch eine neue aufgehoben werden...?

    MfG MAV



  • eher so.

    struct foo : binary_function<string,string,bool> {
       bool operator () (const string &a, const string &b) const {
          return a.length() < b.length();
       }
    };
    
    int main () {
       map<string,int,foo> m;
    
       m["AAA"] = 0;
       m["BB"] = 1;
       m["CCCC"] = 2;
    
    }
    

    wenn du die sortierung ändern willst. map braucht aber irgendeine art von reihenfolge.
    ich denke shade hat hier eine gute lösung gepostet, und die struct Value kann man ja wenn man schreibfaul ist immernoch durch ein std::pair ersetzen.

    ps
    einfach immer null zurückgeben geht natürlich trotzdem nicht bzw bringt nicht das gewünschte ergebnis 😉



  • ui, danke für eure hilfe 😉

    #include <vector>
    #include <boost/shared_ptr.hpp>
    
    using namespace std;
    using boost::shared_ptr;
    
    class myKlasse
    {
    public:
    void SetInt(int x);
    // so daten etc ;)
    };
    
    vector<pair<string, shared_ptr<myKlasse> > vec; // fehler
    

    das gibt leider bei mir nen fehler:
    error C2146: Syntaxfehler : Fehlendes ',' vor Bezeichner 'vec'
    error C2065: 'vec' : nichtdeklarierter Bezeichner
    error C2143: Syntaxfehler : Fehlendes '>' vor ';'
    error C2208: 'class std::vector' : Keine Elemente definiert, die diesen Typ verwenden

    kann mir bitte einer sagen wo mein fehler liegt und wie ich dann vec["AAA"]->SetInt(5); hin bekomme?

    wäre zutiefst dankbar für professionelle hilfe *nein von keinem arzt* 🤡



  • als ergänzung

    map<string, shared_ptr<myKlasse> > element;
    element["AAA"].reset(new MyKlasse(100,100)); // Parameter übergabe an Konstruktor
    element["CCC"].reset(new MyKlasse(100,200));
    element["BBB"].reset(new MyKlasse(100,300));

    so habe ich es und es geht.
    er solls beim begin() end() durchlauf auch in dieser reihenfolge.
    (was momentan ja nicht so ist, da er die arrays sortiert)

    wenn ihr sagt das geht am besten mit vector ist, würd ich das gerne machen.
    habe aber leider meine probs damit, deshalb wäre ich über bissle code über glücklich 😉



  • @davie:
    Wieso sollte man den Functor (ist das ein Functor?) von binary_function erben lassen? 🙂



  • Ich kenne kein assoc Array in welchem die Elemente in der Reihenfolge wie sie hinzugefügt
    werden gespeichert werden, das würde den Zugriff extrem ausbremsen.
    Das beste wäre für dich wolh ein vector< pair< String, int> >, wenn pair 2versch.
    Werte aufnehmen darf.
    Sonst musst du halt ne eigene Klasse schreiben, was ja aber nicht wirklich schwer ist 🙂



  • XguestX schrieb:

    wäre zutiefst dankbar für professionelle hilfe *nein von keinem arzt* 🤡

    Tu mal spitze Klammern zaehlen tun



  • SirLant:
    Muss er nicht, davie hat die Möglichkeit bereits gepostet. bzw.

    struct foo : binary_function<string,string,bool> {
       bool operator () (const string &a, const string &b) const {
          return false;
       }
    };
    

    oder true, k.A., dann sollte das doch funktionieren, oder?
    Wenn er sonst nichts großartig zu sortieren hat, wird er es wohl in der Eintragungsreihenfolge lassen...

    MfG MAV



  • Mis2com schrieb:

    oder true, k.A., dann sollte das doch funktionieren, oder?

    davie schrieb:

    einfach immer null [bzw. true, false oder einen anderen konstanten Wert] zurückgeben geht natürlich trotzdem nicht bzw bringt nicht das gewünschte ergebnis 😉



  • ach fuck ey! hast recht Shade Of Mine, da fehlte nur nen ">" 😮

    #include <vector>
    #include <boost/shared_ptr.hpp>
    
    using namespace std;
    using boost::shared_ptr;
    
    class myKlasse
    {
    public:
    void SetInt(int x);
    // so daten etc ;)
    };
    
    vector< pair<string, shared_ptr<myKlasse> > > element;
    

    vorher:
    map<string, shared_ptr<GUI_Element> > element;
    element["AAA"].reset(new myKlasse(100,100));
    element["AAA"]->SetInt(3);

    auf Azossiatives Array würd ich garnicht so bestehen.
    aber wie mach ich das dann mit:
    vector<shared_ptr<myKlasse> > element;
    element.push_back(???);
    element.push_back(new myKlasse(300,300)); // das geht ja nicht

    und wie rufe ich dann daraus die SetInt(3); auf?

    oh man ich komme mir unter euch so dumm vor 🙄
    würde mich freuen wenn ihr c++ gurus einem nichts das bissle mit sanfter hand nahe bringen könntet 🤡



  • @Mis2Com:
    Das Ableiten von unary_function bzw. binary_function hat denn sinn, dass man standardisierte namen für die argument- und ergebnistypen hat, um sie zb zum Binden weiterverwenden zu können.



  • vielleicht hat wer auch noch ne ganz andere lösung
    sagen wir die myKlasse ist zur darstellung eines buttons
    mit hilfe des assoziativen arrays konnte ich den eintrag in der liste leicht ansprechen element["Button1"]->SetKoord(5,5); das ["Button1"] wurde mir auch helfen das ganze im code zu managen und gezielt anzusprechen.

    wenn ich das jetzt per vector machen soll, sehe ich momentan nicht wie ich gezielt die einzelnen Buttons ansprechen soll und vor allem so das ich die übersicht bewahre. per index sowas zu managen ist nicht übersichtlich, deshalb nahm ich den weg des assoziativen arrays.



  • XguestX schrieb:

    auf Azossiatives Array würd ich garnicht so bestehen.
    aber wie mach ich das dann mit:
    vector<shared_ptr<myKlasse> > element;
    element.push_back(???); 
    element.push_back(new myKlasse(300,300));  // das geht ja nicht
    

    jetzt ganz ohne pair oder mit?

    vector < pair<string, shared_ptr<X> > a;
    a.push_back (make_pair ("String", shared_ptr<X>(new X));
    //bzw.
    vector < shared_ptr<X> > b;
    b.push_back (shared_ptr<X>(new X));
    


  • vector < pair<string, shared_ptr<X> > a;
    a.push_back (make_pair ("String", shared_ptr<X>(new X));

    vector<pair<string, shared_ptr<X> > > vec;
    vec.push_back(make_pair ("String", shared_ptr<X>(new X(300,300))));
    

    sorry aus dem error weerd ich nicht schlau 😕
    error C2536: 'std::pair<char [7],class boost::shared_ptr<class X> >::first' : Angabe einer expliziten Initialisierung fuer Felder nicht moeglich

    Bei der Kompilierung der Member-Funktion '__thiscall std::pair<char [7],class boost::shared_ptr<class X> >::std::pair<char [7],class boost::shared_ptr<class X> >(const char (&)[7],const class boost::shared_ptr<class X> &)' der Klassenvorlage

    und wie greife ich dann auf "String" zu?



  • ?
    probier mal

    vector<pair<string, shared_ptr<X> > > vec;
    vec.push_back(make_pair (string("String"), shared_ptr<X>(new X(300,300))));
    

    zugreifen auf die elemente geht dann so:

    //am besten irgendwo ein typedef machen
    typedef vector <pair<string,shared_ptr<X> > > Assoc; //ist sonst umständlich, wenn man das jedesmal ausschreiben muss
    
    Assoc a;
    a.push_back (make_pair(string("foo"), shared_ptr<X>(new X(300,300))));
    //...
    for (Assoc::iterator i = a.begin(); i != a.end(); ++i) {
       cout << i->first /*das ist der string*/;
       //unter i->second ist dann der shared_ptr
    }
    


  • ja nen durchlauf würd ich schon hinbekommen, mir gehts aber um das explizite ansprechen eines elementes.

    map<string, shared_ptr<X> > element; 
    element["AAA"].reset(new X(100,100)); 
    element["CCC"].reset(new X(100,200)); 
    // viel code text
    element["AAA"]->SetInt(3);
    

    da konnte ich jedes element (klasse) was ich in map ablegte, per assoziatives array leicht ansprechen und deren funktionen nutzen.
    genau das brauch ich ....



  • du verzichtest mit vector auf die sortierung; vector ist jetzt die reihenfolge so, wie du die elemente hinzufügst. also mit vector und ohne element-raussuchen geht es so:

    vec[0].second->foo();
    //der string ist in
    vec[0].first;
    

    andernfalls musst du nach elementen suchen, oder eine map verwenden.



  • ShadeOfMine:
    Aber wieso klappt sowas nicht?

    davie:
    Irgendwie vesteh ich immernoch nicht, was das bringt. 🙄



  • hast du's ausprobiert?
    ein tip: eine map hat keine zwei gleichen elemente.

    noch zu den unary/binary_functions:
    siehe zb

    template <class binary>
    class binder2nd : public unary_function <typename binary::first_argument_type  //hier
                                             typename binary::result_type> { //hier
        binary b;
        typename binary::second_argument_type arg2; //hier
    
    public:
       binder2nd (const binary &x, const typename binary::second_argument_type &v) :  b(x), arg2(v) {} //hier
       result_type operator () (const argument_type &x) const { return op(x,b); } //hier - überall
    };
    

    da verwendet man es, damit später sowas möglich ist:

    list<int>::const_iterator i = find_if (li.begin(), li.end(), bind2nd(less<int>(),7));
    

    d.h. binder2nd verlässt sich zb darauf, eine binary_function zu bekommen.



  • oha, äh, da versteh ich ja echt garnichts von. oO
    Meint ihr, dass kann ich mir alleine mit der MSDN erklären?


Anmelden zum Antworten