Dynarray Implementation



  • Das Ding ist nicht Exceptionsicher.

    Das ist ein großer Fehler, du hast Recht.

    und empty() ist broken.

    Korrigiert.

    ScottZhang schrieb:

    ja das war doof ausgedrückt. ich würde trotzdem swappen.

    Copy operator:

    Dynarray& operator=(Dynarray const& d)
    {
      Dynarray d_copy(d);
      d_copy.swap(*this);
    
      return *this;
    }
    

    Move operator:

    Dynarray& operator=(Dynarray && d)
    {
      d.swap(*this);
      return *this;
    }
    

    Du siehst

    swap
    

    ist enorm wichtig 🙂

    Hmm, ja. 👍

    Bin dran.



  • Shade Of Mine schrieb:

    Aber es ist natuerlich eine nette Uebung.

    Darum gehts. Übung für Eception-Safety und Move-Semantics.

    Allerdings finde ich die Idee gut, im Gegensatz zu dir...



  • Ich glaube, du räumst in der falschen Reihenfolge auf.

    Ich denke, der Sinn einer Standardisierung eines solchen Klassen-Templates liegt in der Optimierungsmöglichkeit, die sich ergibt, wenn Compilerhersteller und Bibliotheks-Autoren gut zusammenarbeiten und für kleine, Funktions-lokale Arrays den Speicher ggf vom Stack holen.



  • Welchen Sinn hat max_size()?
    Und warum gibt es kein non constant data()?

    PS:
    was ich gerne habe ist ein fixed_vector. Also ein vector der wachsen kann, intern aber einen fixen Speicher hat - den er nie reallokiert.



  • Ineffizienter Copyassignment-Operator. Und swap hat da nichts zu suchen.
    Hint: Zuerst schauen ob du Speicher recyclen kannst bevor du neuen allozierst.



  • krümelkacker schrieb:

    Ich glaube, du räumst in der falschen Reihenfolge auf.

    Warte 👍

    Shade Of Mine schrieb:

    Welchen Sinn hat max_size()?

    Gar keinen. Ist raus.



  • So, habe jetzt ein paar try-catch Blöcke hinzugefügt.

    Was die Reihenfolge angeht: da müsste ich nur die _destroy_all -Funktion ändern.



  • ScottZhang schrieb:

    Move operator:

    Dynarray& operator=(Dynarray && d)
    {
      d.swap(*this);
      return *this;
    }
    

    Ähm, nö, so nicht. Das lässt ggf die Objekte, die vorher logisch in *this wohnten zu lange am Leben. Wenn es ein normaler Vector wär, würde man das so machen:

    Dynarray& operator=(Dynarray && d)
    {
      d.swap(*this);
      d.clear();
      return *this;
    }
    

    Im dynarray-Proposal taucht Move-Semantik nicht auf und das ist schätzungsweise Absicht.



  • Im dynarray-Proposal taucht Move-Semantik nicht auf und das ist schätzungsweise Absicht.

    Das Proposal ist von 2008.



  • krümelkacker schrieb:

    Ähm, nö, so nicht. Das lässt ggf die Objekte, die vorher logisch in *this wohnten zu lange am Leben.

    Und was könnte dadurch passieren?



  • Sone schrieb:

    Im dynarray-Proposal taucht Move-Semantik nicht auf und das ist schätzungsweise Absicht.

    Das Proposal ist von 2008.

    Move-Semantik ist noch nicht sooo jung. Ich kann aber vorstellen, dass es was mit dem zu tun hat, was ich vorhin um 17:43 Uhr ansprach, nämlich, der Stack-Speicher-Optimierung. Das wäre dann eine nette Alternative zu VLAs. Wie gesagt, ich denke, das ist der Grund, warum es überhaupt dieses Proposal gibt. Man will so etwas wie VLAs haben, ohne dafür am Sprachkern "rumzufummeln".



  • krümelkacker schrieb:

    Sone schrieb:

    Im dynarray-Proposal taucht Move-Semantik nicht auf und das ist schätzungsweise Absicht.

    Das Proposal ist von 2008.

    Move-Semantik ist noch nicht sooo jung. Ich kann aber vorstellen, dass es was mit dem zu tun hat, was ich vorhin um 17:43 Uhr ansprach, nämlich, der Stack-Speicher-Optimierung. Das wäre dann eine nette Alternative zu VLAs. Wie gesagt, ich denke, das ist der Grund, warum es überhaupt dieses Proposal gibt. Man will so etwas wie VLAs haben, ohne dafür am Sprachkern "rumzufummeln".

    👍

    So, habe den Code jetzt verändert.

    Kann sich das bitte jemand reinziehen? 😃



  • ScottZhang schrieb:

    krümelkacker schrieb:

    Ähm, nö, so nicht. Das lässt ggf die Objekte, die vorher logisch in *this wohnten zu lange am Leben.

    Und was könnte dadurch passieren?

    Siehe
    http://cpp-next.com/archive/2009/09/your-next-assignment/



  • krümelkacker schrieb:

    ScottZhang schrieb:

    krümelkacker schrieb:

    Ähm, nö, so nicht. Das lässt ggf die Objekte, die vorher logisch in *this wohnten zu lange am Leben.

    Und was könnte dadurch passieren?

    Siehe
    http://cpp-next.com/archive/2009/09/your-next-assignment/

    👍 Danke

    Edit: Ich fange an C++ zu hassen, hier geht aber auch nix naiv :xmas1: ... nee nur spass



  • Wo genau liegt jetzt der Vorteil dieser Implementierung gegenüber std::vector ?

    Und warum and etc.? Du bist so ziemlich der einzige, der das heutzutage noch verwendet, und verwirrst damit viele Programmierer nur. Und warum kein std::swap() in Dynarray::swap() ? Im Nahezu-Move-Konstruktor den Zuweisungsoperator aufzurufen ist auch unüblich, gerade wenn man den Allokator damit wegwirft. using namespace im Header ist nicht gut. Wie du auf Fehler bei der Zerstörung reagierst, ist auch interessant. Gibt sicher noch Weiteres...



  • Nexus schrieb:

    Wo genau liegt jetzt der Vorteil dieser Implementierung gegenüber std::vector ?

    Sieh erster Satz in meinem ersten Posting. Da kommt das Wort Spaß drin vor 😃

    Und warum and etc.? Du bist so ziemlich der einzige, der das heutzutage noch verwendet, und verwirrst damit viele Programmierer nur.

    "etc."? Welches ecetera?
    and ist weg.

    Nexus schrieb:

    Und warum kein std::swap() in Dynarray::swap() ?

    Done.

    Nexus schrieb:

    Im Nahezu-Move-Konstruktor den Zuweisungsoperator aufzurufen ist auch unüblich, gerade wenn man den Allokator damit wegwirft.

    Hä? Ich initialisiere meinen doch direkt darüber!
    Kurze Nebenfrage: Sollte ich den Allokator bei einer Zuweisung weitergeben?
    Ja, oder?

    Nexus schrieb:

    using namespace im Header ist nicht gut.

    Hab jetzt die Vergleichsoperatoren weggelassen, das ist momentan eh unnötig.

    Nexus schrieb:

    Wie du auf Fehler bei der Zerstörung reagierst, ist auch interessant.

    Jetzt aber ehrlich... ist es nur interessant oder ist das reinste Untertreibung?
    Sehr ungeübt in solchen Sachen. Muss mir mal Exceptional C++ zulegen. 😃

    Gibt sicher noch Weiteres...

    Dafür habe ich ja euch... :xmas1:


  • Mod

    Ein paar Bemerkungen

    1. vom Allokator (privat) ableiten zwecks EBO
    2. _clean : exceptions könnten nur von Destruktoren stammen, relativ sinnlos, damit umgehen zu wollen, zudem werden dann nicht alle Objekte zerstört
    3. InputIteratoren sind nur für single-pass-Algorithmen gut - der Range-Konstruktor benötigt mindestens ForwardIterator
    4. Konstruktoren werden nicht über Zuweisung implementiert.
    5. Die Zuweisungsoperatoren sind jetzt mehrdeutig für rvalues.
    6. Der Moveoperator kann nicht korrekt mit self-move umgehen.
    7. Exceptionspezifikationen alten Stils sind zu vermeiden
    8. swap sollte noexcept sein, und wird zweckmäßigerweise über swap für die einzelnen Member implementiert
    9. noexcept für Destruktor, move-Konstruktor/Zuweisung etc.



  • Das man die einzelnen Member tauschen sollte war mir klar! Da kam Nexus daher...

    Habe alle Sachen berücksichtigt (bis auf ein, zwei). Kannst es dir noch mal ansehen? :xmas1:

    Als ich campers Namen gesehen habe, wusste ich, jetzt kommt was 😃



  • camper schrieb:

    9. noexcept für Destruktor, move-Konstruktor/Zuweisung etc.

    Schwierige Sache, da schon im Dtor das deallokieren vom Allokator nicht zwangsläufig nothrow sein muss.
    (Oder das zerstören der Feldelemente)



  • Und noch eine Frage:
    soll ich
    allocator_type::propagate_on_container_copy_assignment , `

    allocator_type::propagate_on_container_move_assignment und

    allocator_type::propagate_on_container_swap

    `
    Mit einbeziehen?


Anmelden zum Antworten