std::list Implementierung
-
314159265358979 schrieb:
Werner Salomon schrieb:
Du verwendest zwei Anker-Knoten first und last. Meines Erachtens ist nur ein Ankerknoten notwendig, der auf sich selbst zeigt, falls die Liste leer ist.
Ist nötig für die Iteratoren
die brauchen auch nur einen. end() zeigt auf den einen ungültigen Knoten der den Ring schließt, und begin() zeigt auf den ersten Knoten dahinter.
//edit block entfernt, mach nen post draus...ihr seid zu schnell .
-
Wie auch immer, ist so einfacher zu implementieren.
-
314159265358979 schrieb:
Werner Salomon schrieb:
Du verwendest zwei Anker-Knoten first und last. Meines Erachtens ist nur ein Ankerknoten notwendig, der auf sich selbst zeigt, falls die Liste leer ist.
Ist nötig für die Iteratoren
Nö - begin() zeigt auf das erste Element und end() auf den Anker. Ein zweiter Anker ist unnötig.
314159265358979 schrieb:
Werner Salomon schrieb:
Im Konstruktor von ListNode kann man prev und next nicht mitgeben. Wenn Du noch einen hinzufüst, so würde sich das List::init erledigen.
Kann man machen, mir gefällts so besser
Ist aber bestimmt 'ne halbe nano-Sekunde langsamer, da prev und next zwei mal initialisiert werden. Außerdem geht bei mir immer die gelbe Warnleuchte an, wenn ich init() lese
Gruß
Werner
-
Werner Salomon schrieb:
Nö - begin() zeigt auf das erste Element und end() auf den Anker. Ein zweiter Anker ist unnötig.
Siehe erste Seite
Werner Salomon schrieb:
Ist aber bestimmt 'ne halbe nano-Sekunde langsamer, da prev und next zwei mal initialisiert werden. Außerdem geht bei mir immer die gelbe Warnleuchte an, wenn ich init() lese
Der Compiler müsste das doch eigentlich wegoptimieren können, oder?
-
(war vorher ein edit, aber ihr postet zu schnell):
Ws mich stört:
Was ich an der std::list niemals mochte war, dass für jedes neue Element new aufgerufen wurde. in der std::list wurde das noch durch einen Allokator gelöst an dem man selbst rumpfuschen konnte, hier geht das nicht. Besser wäre es(meiner Meinung nach), wenn die Liste den Speicher immer Blockweise allokieren würde. Dann muss man sich nicht schlagen, wenn man regelmäßig Elemente aus der Liste entfernen/einfügen muss...
-
otze schrieb:
(war vorher ein edit, aber ihr postet zu schnell):
Ws mich stört:
Was ich an der std::list niemals mochte war, dass für jedes neue Element new aufgerufen wurde. in der std::list wurde das noch durch einen Allokator gelöst an dem man selbst rumpfuschen konnte, hier geht das nicht. Besser wäre es(meiner Meinung nach), wenn die Liste den Speicher immer Blockweise allokieren würde. Dann muss man sich nicht schlagen, wenn man regelmäßig Elemente aus der Liste entfernen/einfügen muss...Auf Allokatoren habe ich der Einfachheit halber bewusst verzichtet
-
314159265358979 schrieb:
Feedback bitte
Warum eigentlich?
-
Werner Salomon schrieb:
314159265358979 schrieb:
Feedback bitte
Warum eigentlich?
Weil ich wissen möchte, ob noch jemandem etwas auffällt, das total falsch oder schöner/besser/schneller zu lösen ist. Bin halt ein Perfektionist
-
Neben der fehlenden iterator -> const_iterator Konvertierung ist mir noch etwas aufgefallen. Du verwendest überall Schleifen der Art
for (auto&& iter = list.begin(); iter != list.end(); ++iter) ...
wobei hinter dem auto ein && sitzt. Das ist aber eigentlich überflüssig. list.end() wird (logisch) auch jedes Mal aufgerufen.
Und ich sehe gerade noch, dass der Selbstzuweisungstest beim operator=(List) nicht nötig ist.
-
krümelkacker schrieb:
Neben der fehlenden iterator -> const_iterator Konvertierung ist mir noch etwas aufgefallen.
Wäre es ratsamer in iterator einen operator const_iterator() zu definieren, oder dem const_iterator einen iterator-Konstrukor zu geben?
krümelkacker schrieb:
wobei hinter dem auto ein && sitzt. Das ist aber eigentlich überflüssig.
Was zur Folge hat, dass der Returnwert gemoved wird. Dass das wenig bringt, ist mir klar.
krümelkacker schrieb:
list.end() wird (logisch) auch jedes Mal aufgerufen.
Natürlich könnte ich die Schleife so umschreiben:
for(auto&& iter = list.begin(), end = list.end(); iter != end; ++iter) ...
Aber kann der Compiler das nicht von selbst optimieren?
krümelkacker schrieb:
Und ich sehe gerade noch, dass der Selbstzuweisungstest beim operator=(List) nicht nötig ist.
Danke, habe ich übersehen
-
314159265358979 schrieb:
Weil ich wissen möchte, ob noch jemandem etwas auffällt, das total falsch oder schöner/besser/schneller zu lösen ist. Bin halt ein Perfektionist
Warum lehnst du dann alle verbesserungs vorschlaege ab?
-
Shade Of Mine schrieb:
314159265358979 schrieb:
Weil ich wissen möchte, ob noch jemandem etwas auffällt, das total falsch oder schöner/besser/schneller zu lösen ist. Bin halt ein Perfektionist
Warum lehnst du dann alle verbesserungs vorschlaege ab?
Tue ich doch gar nicht, vielleicht habe ich mich schlecht ausgedrückt, ich möchte es erstmal bei der vorhandenen Funktionalität belassen
-
314159265358979 schrieb:
krümelkacker schrieb:
wobei hinter dem auto ein && sitzt. Das ist aber eigentlich überflüssig.
Was zur Folge hat, dass der Returnwert gemoved wird.
Wie bitte? Was wird wohin "gemoved"?
-
Normalerweise wird der Returnwert kopiert, mit && gemoved. Jaja, ich weiß, copy elision, aber ich habs mir angewöhnt den Returnwert aus Funktionen mit && zu moven. Und langsamer kanns dadurch ja nicht werden
-
314159265358979 schrieb:
Normalerweise wird der Returnwert kopiert, mit && gemoved. Jaja, ich weiß, copy elision, aber ich habs mir angewöhnt den Returnwert aus Funktionen mit && zu moven. Und langsamer kanns dadurch ja nicht werden
Aber "gemoved" wird hier gar nichts. Du bindest lediglich eine Rvalue-Referenz an ein temporäres Objekt, dessen Lebenszeit dann verlängert wird.
-
krümelkacker schrieb:
314159265358979 schrieb:
Normalerweise wird der Returnwert kopiert, mit && gemoved. Jaja, ich weiß, copy elision, aber ich habs mir angewöhnt den Returnwert aus Funktionen mit && zu moven. Und langsamer kanns dadurch ja nicht werden
Aber "gemoved" wird hier gar nichts. Du bindest lediglich eine Rvalue-Referenz an ein temporäres Objekt, dessen Lebenszeit dann verlängert wird.
Da hast du Recht, habe das wohl verwechselt, jedenfalls war es so gemeint