Anzahl gleicher Elemente mit equal_range berechnen



  • zwei Fehler weniger, danke 🙂

    jetzt sieht es aber so aus
    http://www.imagenetz.de/f13ea4222/unbenannt.PNG.html

    wozu brauche ich bitte den <-operator? ich vergleiche ja nur auf gleichheit?

    was genau wird mit den deduce+<-operator-fehlern gemeint?



  • Ganz einfach: Wahrscheinlich in equal_range wird upper_bound aufgerufen, und in upper_bound wird ein Vergleich zwischen zwei Objekten vom Typ Element gemacht.
    Da du aber die entsprechenden Operator nicht überladen hast, gibt es einen Fehler.

    Weiß ich aber nicht genau, ich hab nicht die Header von VC++.





  • man seit ihr gut 🕶
    ihr habt recht, hätte genauer recherchieren müssen 👍

    jetzt habe ich aber einen type-mismatch:

    Error 1 error C2678: binary '<' : no operator found which takes a
    left-hand operand of type 'const int' (or there is no acceptable conversion)
    c:\program files (x86)\microsoft visual studio 10.0\vc\include
    \algorithm 2890

    bool operator <(const Element& E, const Element &R)
    {
    	if (E.ngen < R.ngen)
    		return true;
    	else return false;
    	return false;
    }
    

    wo muss ich hier den const noch schreiben?



  • ACnut schrieb:

    man seit ihr gut 🕶
    ihr habt recht, hätte genauer recherchieren müssen 👍

    jetzt habe ich aber einen type-mismatch:

    Error 1 error C2678: binary '<' : no operator found which takes a
    left-hand operand of type 'const int' (or there is no acceptable conversion)
    c:\program files (x86)\microsoft visual studio 10.0\vc\include
    \algorithm 2890

    bool operator <(const Element& E, const Element &R)
    {
    	if (E.ngen < R.ngen)
    		return true;
    	else return false;
    	return false;
    }
    

    wo muss ich hier den const noch schreiben?

    Der Operator ist hübsch.
    Aber ich hätte friend davorgeschrieben, damit er zur freien Funktion außerhalb der Klasse wird.



  • bool operator <(const Element& E, const Element &R) 
    { 
        if (E.ngen < R.ngen) 
            return true; 
        else return false; 
        return false; 
    }
    

    ➡

    bool operator <(const Element& E, const Element &R) 
    { 
        return E.ngen < R.ngen; 
    }
    


  • range=equal_range(vect.begin(),vect.end(),vect[0].ngen);
    

    soll vermutlich

    range=equal_range(vect.begin(),vect.end(),vect[0]);
    

    sein.



  • volkard vielen dank

    wenn ich die funktion als friend definiere muss ich die methode auch in der klasse haben?

    offtopic: wann muss ich die operatorüberladung innerhalb der klasse haben, denn bis jetzt hab ich es immer außerhalb geschrieben

    mfg
    ACnut



  • ACnut schrieb:

    volkard vielen dank

    wenn ich die funktion als friend definiere muss ich die methode auch in der klasse haben?

    offtopic: wann muss ich die operatorüberladung innerhalb der klasse haben, denn bis jetzt hab ich es immer außerhalb geschrieben

    mfg
    ACnut

    Außerhalb ist gut.
    Als friend darf man sie innerhalb schreiben, sie ist aber dann auch in Wirklichkeit außerhalb.

    Innerhalb würde der Operator den linken Parameter implizit als *this mitkriegen und in den Parameterklammern würde nur noch die rechte Seite stehen. Das ist unhübsch. Und manchmal sogar schlecht.



  • ah gut zu wissen 🙂

    das heißt innerhalb der klasse würde die funktion so aussehen?

    bool Element:: operator <(const Element& E)
    {
        Element blabla(*this);
        return blabla.ngen < E.ngen;
    }
    


  • bool Element::operator <(const Element& E)
    {
        return (*this).ngen < E.ngen;
    }
    

    oder

    bool Element::operator <(const Element& E)
    {
        return this->ngen < E.ngen;
    }
    

    oder

    bool Element::operator <(const Element& E)
    {
        return ngen < E.ngen;
    }
    

    oder

    bool Element:: operator <(const Element& E)
    {
        Element& blabla=*this;
        return blabla.ngen < E.ngen;
    }
    


  • ACnut schrieb:

    ah gut zu wissen 🙂

    das heißt innerhalb der klasse würde die funktion so aussehen?

    bool Element:: operator <(const Element& E)
    {
        Element blabla(*this);
        return blabla.ngen < E.ngen;
    }
    

    Die Qualifizierung mit dem Klassennamen (Element::) musst du weglassen, das muss eine unqualified-id sein.

    Die Variante mit der Operatorfunktion als Memberfunktion hat einen Nachteil: Falls die Klasse, für die der Operator überladen wird, einen Konvertierungskonstruktor bereitstellt, kann dieser bei der Deklaration als Member nicht ausgenutzt werden. Komische Semantik:

    struct MyClass
    {
        int val;
    
        MyClass(int val):
            val(val) {}
    
        bool operator<( MyClass const& c ) const
        {
            return val < c.val;
        }
    };
    
    int main()
    {
        if( MyClass(7) < 4 ) // Das geht noch
            // ...
        if( 4 < MyClass(4) ) // Wums. Nicht möglich.
            // ...
    }
    


  • das heißt innerhalb der klasse würde die funktion so aussehen?

    volkard schrieb:

    ..

    Alles falsch :p



  • Mmm, sicher Sone:
    http://ideone.com/xQQE5V



  • Nathan schrieb:

    Mmm, sicher Sone:
    http://ideone.com/xQQE5V

    Es ging mir um die Definition in der Klasse http://ideone.com/hiNh2r



  • Sone schrieb:

    Nathan schrieb:

    Mmm, sicher Sone:
    http://ideone.com/xQQE5V

    Es ging mir um die Definition in der Klasse http://ideone.com/hiNh2r

    Und ging es darum, daß die Funktion in der Klasse ist.



  • Sone schrieb:

    http://ideone.com/hiNh2r

    GCC 3.9 hätte das akzeptiert.



  • volkard schrieb:

    Sone schrieb:

    Nathan schrieb:

    Mmm, sicher Sone:
    http://ideone.com/xQQE5V

    Es ging mir um die Definition in der Klasse http://ideone.com/hiNh2r

    Und ging es darum, daß die Funktion in der Klasse ist.

    Naja, ich dachte jetzt, in der Klasse heißt in der Klasse. 😋

    Übrigens, wenn du den kleiner-als Operator überlädst, solltest du auch immer direkt den ist-gleich Operator mit überladen. Die kommen meistens im Zweierpack.

    bool Element:: operator <(const Element& E) 
    { 
        Element blabla(*this); 
        return blabla.ngen < E.ngen; 
    }
    

    Wieso eine Kopie?
    Volkards dritte Lösung ist die gängigste.



  • Sone schrieb:

    Übrigens, wenn du den kleiner-als Operator überlädst, solltest du auch immer direkt den ist-gleich Operator mit überladen. Die kommen meistens im Zweierpack.

    Wozu? operator< reicht doch immer völlig.

    Dazu noch ein kleines Rätsel:

    std::cout << std::boolalpha << (x < y || y < x || x == y) << '\n';
    // Ausgabe: false
    

    x, y sind dabei von Typen aus reinem C++.



  • lazyprogger schrieb:

    Sone schrieb:

    Übrigens, wenn du den kleiner-als Operator überlädst, solltest du auch immer direkt den ist-gleich Operator mit überladen. Die kommen meistens im Zweierpack.

    Wozu? operator< reicht doch immer völlig.

    stl-algos verwenden eigentlich je nach dem, den op< oder den o==. und daraus werden sich die anderen vier gebaut. den op== aus dem op< zu bauen, kann lahm sein.
    deshalb sollte man die beiden anbieten.


Anmelden zum Antworten