operator[] zweimal deklarieren?



  • Guten Tag!

    Mich quält wieder mal eine Frage, und zwar gehts diesmal um das Überladen
    vom operator[]. Bjarne Stroustrup bringt in seinem Buch als Beispiel ein
    assoziatives Feld (§11.8), das wie folgt definiert wird:

    class Assoc {
        // ...
    
    public:
        // ...
        const double& operator[](const string&);
        double& operator[](string&);
    };
    

    Der operator[] wird also zweimal deklariert. Wozu?

    Allerdings wird nur die zweite Elementfunktion definiert:

    double& Assoc::operator[](string& s)
    {
        // ...
    }
    

    Ich war etwas verwundert, dass sich der Compiler nicht beschwert hat, dass
    die erste Elementfunktion nirgends definiert sei.

    Wird die Elementfunktion mit der konstanten Referenz nicht sowieso
    der anderen bevorzugt? Oder unter welchen Umständen würde die zweite
    aufgerufen werden?

    Ich hätte den operator[] so deklariert:

    class Assoc {
        // ...
    
    public:
        double& operator[](const string&);
    };
    

    Da der string ja nicht von der Elementfunktion verändert wird, verstehe ich
    nicht ganz, wozu eine Version deklariert wird, die ein nicht-konstantes
    Stringreferenz-Argument übergeben bekommt.

    Und welchen Sinn hat es, eine konstante Referenz zurückzugeben?

    gruß,
    walker



  • Kann es sein, dass du da was verwechselt hast und der Unterschied eigentlich so aussieht?

    const double& operator[](const string&) const;
          double& operator[](const string&);
    

    Das würde mehr Sinn machen.

    Der eine Operator, falls man ein konstantes Objekt der Klasse hat und der andere, falls man den double ändern will.



  • Und welchen Sinn hat es, eine konstante Referenz zurückzugeben?

    Wenn man ein konstantes Objekt hat, will man ja, dass es sich nicht verändern kann. Würde man eine nicht-konstante Referenz auf interne Daten zurückgeben, ginge das dennoch:

    void func(const Assoc& obj)
    {
      double& x = obj[0];
      x = 123;
    }
    

    Und das will man ja nicht.



  • DrGreenthumb schrieb:

    Kann es sein, dass du da was verwechselt hast und der Unterschied eigentlich so aussieht?

    const double& operator[](const string&) const;
          double& operator[](const string&);
    

    So leuchtet mir das natürlich auch ein 🙂

    Ist wahrscheinlich ein Fehler im Buch...
    Kann mir das noch jemand bestätigen der die deutsche Übersetzung auch hat? 🤡

    Vielen Dank für die bisherige Antwort!

    gruß,
    walker



  • tatsächlich hat er es so geschrieben. hab auch bei den errata nix gefunden.


Anmelden zum Antworten