std::pair<std::string, std::string> ueberladen operator<()



  • Also ich will einen pair ueberladen.

    Ich hab folgendes gemacht:

    typedef std::pair<std::string, std::string> bla;
    bool operator<(const bla a, const bla b){ return (a.first).size()<(a.first).size(); }
    
    std::priority_queue<bla>, std::vector<bla>, std::greater<bla> > que;
    que.push(bla("test","test");
    

    Im queue soll dann immer der kleinste string Oben sein.
    Kann das so gehen?
    Ich hab zwar den code gschrieben, aber ich habe noch das element
    std::greater eingebunden. Der greater bindet binaere stroeme.
    was ist damit gemeint?

    Das mit den std::bind1st(); und std::bind2nd() hab ich einigermasen verstanden.
    um alles zu loeschen ueber 8.:

    std::vector<int> bla;
    //fuellen
    bla.erase(remove_if(bla.begin(), bla.end(), std::bind2nd(greater<int>(), 8)), bla.end());
    

    Nur ein schnell geschriebenes beispiel. Kann noch fehler haben.

    Hoffe das es einigermasen klar ist. Bin etwas confuse 😕

    Danke, Ghost



  • Anders gefragt:
    Wie wuerdet ihr einen priority_queue machen, der einen pair beinhaltet?
    Der kleinste String des pair (first) sollte oben sein.



  • Wenn du greater verwendest, dann solltest du auch den richtigen Operator verwenden (>), also (habe auch noch ein paar Schreibfehler korrigiert)

    bool operator>(const bla& a, const bla& b){ return (a.first).size()<(b.first).size(); } 
    
    std::priority_queue<bla, std::vector<bla>, std::greater<bla> > que; 
    que.push(bla("test","test"));
    

    oder noch besser ist es, eine Functor-Klasse zu verwenden...



  • Das mit den schreib Fehlern hab ich schon bemerkt.
    Meine Finger waren wieder schneller als der Kopf 😉

    Also bei std::sort(); braucht man (<)
    und bei std::greater() den (>)
    Hab ich das Richtig verstanden?

    Mit Functor-Klasse meinst du:

    class foo{
     public:
      std::string first, second;
      foo(std::string a, std::string b){ first=a; second=b; }
      bool operator<(const foo a, const foo b){ return (a.first).size()<(b.first).size(); }
      foo & operator=(foo &b){ this->first=b.first; this->second=b.second; return *this; }
    }:
    

    Oder was anderes?



  • ??
    ich will mein struct compilieren, aber es geht nicht??
    Hab es doch immer so gemacht...
    Hat jemand einen Tipp?

    struct Edg{
      std::string first,second;
      Edg(std::string a, std::string b){ first=a; second=b; }
      bool operator<(const Edg r, const Edg k){ return (r.first).size()<(k.first).size(); }
      Edg & operator=(Edg &b){ this->first=b.first; this->second=b.second; return *this; }
    };
    

    Compile fehler:

    /home/aufgabe5-operatoren/aufgabe5.cpp:18: error: `bool Edg::operator<(Edg, Edg)' must
       take exactly one argument
    

    Kann sein das der operator= falsch geschrieben ist, ich uebe noch mit den operatoren.

    Danke, Ghost



  • friend bool operator<(const Edg r, const Edg k){ return (r.first).size()<(k.first).size(); }
    

    So geht es.
    Kann mir wenigsten jemand sagen wieso das so geht?

    Danke, Ghost



  • Green_Ghost schrieb:

    Anders gefragt:
    Wie wuerdet ihr einen priority_queue machen, der einen pair beinhaltet?

    Da du nur das erste Element des Pairs vergleichst, würde ich ein extra Prädikat schreiben. Z.B. so:

    class FirstGreater
    {
    public:
        template <class F, class S>
        bool operator()(const std::pair<F, S>& lhs, const std::pair<F, S>& rhs) const
        {
           return lhs.first > rhs.first;
        }
    };
    
    int main()
    {
        typedef std::pair<std::string, std::string> StrPair;
        typedef std::priority_queue<StrPair, std::vector<StrPair>, FirstGreater> PriorityQueue;
        PriorityQueue pq;
        pq.push(StrPair("a", "b"));
        pq.push(StrPair("b", "a"));
        assert(pq.top().first == "a");
    }
    

    Green_Ghost schrieb:

    ??
    ich will mein struct compilieren, aber es geht nicht??
    Hab es doch immer so gemacht...
    Hat jemand einen Tipp?

    struct Edg{
      std::string first,second;
      Edg(std::string a, std::string b){ first=a; second=b; }
      bool operator<(const Edg r, const Edg k){ return (r.first).size()<(k.first).size(); }
      Edg & operator=(Edg &b){ this->first=b.first; this->second=b.second; return *this; }
    };
    

    Das kann auch nicht gehen. < ist ein binärer Operator, da du ihn nun aber als Memberfunktion deklarierst und Memberfunktionen ein implizites erstes Argument besitzen (this) deklarierst du ihn so als ternären Operator -> Fehler.
    Wenn du den op< als Member haben willst, dann musst du nur noch den rechten Operand angeben. Der linke ist implizit das aufrufende Objekt:

    struct Edg{
      std::string first,second;
      ...
      bool operator<(const Edg& rhs) const { 
        return first.size()< rhs.first.size(); 
      }
    };
    

    Green_Ghost schrieb:

    friend bool operator<(const Edg r, const Edg k){ return (r.first).size()<(k.first).size(); }
    

    So geht es.

    Logisch. Durch die Deklaration als friend wir der Operator automatisch zu einer freien Funktion. Auch wenn du ihn innerhalb der Klassendefinition definierst.

    Am Sinnvollsten ist es allerdings, wenn du den operator< gleich als non-member-non-friend definierst:

    struct Edg{
      std::string first,second;
      ...
    }; 
    bool operator<(const Edg& r, const Edg& k){ return r.first.size()<k.first.size(); 
    }
    


  • Danke, hab viel gelernt.
    Muss mich wohl wieder dahinter setzen (Member/Klassen/...).

    Nochmals Danke,

    Ghost


Anmelden zum Antworten