Unverständlichkeiten in der Implementierung von CheckedIter in Stroustrups Buch



  • Hi Community, 👍 👍

    ich bin neu hier und freue mich sehr meine Fragen an Euch stellen (und vielleicht auch gelegentlich ein Paar Fragen anderer beantworten) zu
    dürfen. So dann gehts auch schon unverzüglich an meine zwei Fragen:

    Es geht um die Implementierung von CheckedIter in Stroustrups Buch, die ich an zwei Stellen nicht ganz verstanden habe, erst die unwichtigere Frage:

    akt ist der ungeprüfte Iterator für die aktuelle Position
    c ist der Zeiger zum Container von akt

    *reference operator() const
    {
    if (akt==c->end()) throw out_of_bounds();
    return *akt;
    }

    pointer operator->() const
    {
    if(akt==c->end()) throw out_of_bounds();
    return &*akt; //durch * schon geprüft
    }**

    Die Frage ist, warum im Kommentar "durch * schon geprüft" steht. Welches ***** ist damit gemeint (vielleicht hat man am besten den ganzen Code selber zur Überprüfung bereit 🙂 ). Hier wird wohl kaum der eigene operator()* von CheckedIter gemeint sein, da bei der return-Anweisung von operator->() der eigene operator()* des ungeprüften Iterators akt benutzt wird. Und wenn es durch ***** schon geprüft wäre wird doch, wie in der Implementierung des operator->() von CheckedIter zu sehen ist, dennoch durch die if-Anweisung geprüft, also dann doppelt geprüft. Sehe ich da was falsch??

    Zur zweiten Frage:

    CheckedIter operator+(difference_type d) const
    {
    if (c->end()-akt < d || d < akt-c->begin()) throw out_of_bounds();
    return CheckedIter(c,akt+d);
    }

    Okay, meinen Einwand gegen diesen Code illustriere ich am besten mit einem Beispiel:

    c->end sei c[10]
    akt stehe bei c[4]
    ich will, dass akt zu c[6] weiterwandert, also gebe ich für d = 2 ein

    somit wäre die erste Teilbedingung der if-Abfrage nicht erfüllt:
    c->end()-akt < d => 6 < 2 FALSCH, also würde kein out_of_bouds() geworfen werden

    aber nach der zweiten Teilbedingung würde gelten
    d < akt-c->begin() => 2 < 4 RICHTIG, da die Teilbedingungen miteinander verodert wurden wäre die Gesamtbedingung somit richtig und es würde ein out_of_bounds() geworfen, obwohl d = 2 unter den gegebenen Bedingungen kein out_of_bounds() erzeugen dürfte. Die beinahe identische if-Bedingung ist auch bei der Implementierung von operator[]() vorhanden. Sehe ich da was falsch?

    Vielen dank im voraus 🙂


  • Mod

    cilker schrieb:

    pointer operator->() const
    {
       if(akt==c->end()) throw out_of_bounds();
       return &*akt;                           //durch * schon geprüft
    }
    

    Das sollte besser

    pointer operator->() const
    {
       return &**this;
    }
    

    heißen. Es kann aber sein, dass es bereits ein entsprechendes Errata gibt, da müsstest du einfach mal auf Stroustrups Seite nachscheuen.

    Zur zweiten Frage:

    CheckedIter operator+(difference_type d) const
    {
       if (c->end()-akt < d || d < akt-c->begin()) throw out_of_bounds();
       return CheckedIter(c,akt+d);
    }
    

    Das muss nat.

    d < c->begin()-akt
    

    heißen. Wie geesagt, möglicherweise gibt es dazu bereits eine Korrektur.



  • Ja danke camper, bei deinen Versionen habe ich absolut nix mehr zu beanstanden thx 🙂


Anmelden zum Antworten