std::stack / Wieso keine clear Methode?



  • camper schrieb:

    std::stack ist doch sowieso die mit Abstand überflüssigste Komponente der Standardbibliothek. Wozu darüber streiten?

    👍


  • Administrator

    camper schrieb:

    std::stack ist doch sowieso die mit Abstand überflüssigste Komponente der Standardbibliothek. Wozu darüber streiten?

    Wir können es noch erweitern auf std::queue und std::priority_queue , aber irgendwie beschleicht mich das Gefühl, dass du diese auch als überflüssig ansehen wirst 🙂

    Aber wie gesagt, mich würde eigentlich hauptsächlich interessieren, wieso das Standard-Komitee so entschieden hat. Bis jetzt haben eigentlich alle nur irgendwelche Behauptungen aufgestellt, die allerdings meiner Meinung nach alle keinen Boden unter den Füssen haben.

    Grüssli



  • "add esp, 8"

    da wird die CPU trozdem die variablen nacheinander aufräumen nehm ich an oder ist quasie der clear befehl, und clear räumt die elemente auch nacheinder weg^^



  • BorisDieKlinge schrieb:

    "add esp, 8"

    da wird die CPU trozdem die variablen nacheinander aufräumen nehm ich an oder ist quasie der clear befehl, und clear räumt die elemente auch nacheinder weg^^

    Nein, das ist ein arithmetischer Befehl, bekannt als Addition. Den kann die CPU schon in einem Schritt ausführen.



  • Dravere schrieb:

    ...Das mit deinem Beispiel funktioniert leider nicht. Und zwar aus dem Grund, weil man ein Stack auch leeren kann, indem man der Reihe nach alle Elemente vom Stack runternimmt. Und wenn das erst noch effizient geht, über eine zusätzliche Methode, wieso sollte man diese nicht implementieren?...

    Neeee.
    Dein "selbstgebasteltes Stack-Clear" ist strukturell etwas anderes als ein clear() auf den zugrundeliegen Container. Es mag zwar in einigen Implementierungen denselben Effekt haben, aber das bedeutet noch lange nicht, dass es dasselbe sei ... einem stack wäre z.B. durchaus erlaubt, bei pop() lediglich einen "actElement-Zeiger" zu verschieben.

    Nochmal: Bloß weil ein Stack seine Funktionialität intern über einen Container implementiert, bedeutet es noch lange nicht, dass er ein solcher ist.

    Stell Dir "Stack" eher wie ein Design-Pattern vor, das für einen spezifischen Zweck entsprechende Funktionalitäten bietet. Mehr ist nicht seine Aufgabe und es wäre IMHO sogar schlecht, wenn es darüber hinaus implementierungsspezifische Funktionalitäten nach außen weiterleitet.

    Gruß,

    Simon2.


  • Administrator

    Simon2 schrieb:

    Dein "selbstgebasteltes Stack-Clear" ist strukturell etwas anderes als ein clear() auf den zugrundeliegen Container. Es mag zwar in einigen Implementierungen denselben Effekt haben, aber das bedeutet noch lange nicht, dass es dasselbe sei ... einem stack wäre z.B. durchaus erlaubt, bei pop() lediglich einen "actElement-Zeiger" zu verschieben.

    Es kann ja dann auch frei definiert werden, was bei einem clear passiert. Bei einem std::vektor, wird der Speicher auch nicht freigegeben. Das ist dann demjenigen überlassen, welcher den Container schreibt. Ob da ein Zeiger verschoben wird, der Speicher freigegeben wird, oder "blau" auf der Konsole rauskommt, ist völlig egal. std::stack ist ja nur ein Adapter, welcher die Aufrufe direkt an den Container weiterleitet. std::stack selber macht eigentlich gar nichts! Und somit könnte er auch einfach direkt ein clear weiterleiten. Wenn du willst, sogar ein stack_clear oder sowas, wobei ich das allerdings unnötig fände.

    Simon2 schrieb:

    Nochmal: Bloß weil ein Stack seine Funktionialität intern über einen Container implementiert, bedeutet es noch lange nicht, dass er ein solcher ist.

    Das haben ich jetzt schon zigg tausend Male gehört, dabei noch gar nie behauptet!

    Grüssli



  • Dravere schrieb:

    ...
    Es kann ja dann auch frei definiert werden, was bei einem clear passiert. ...

    Klar - aber auch das ist nicht der Punkt, auf den ich hinauswill. Sondern: "Dein Stack-clear" != "<zugrundeliegender-Container>.clear()"
    ... diese Ungleichheit bedeutet, dass Deine Aussage "Ich kann's selbst basteln" nicht stimmt.

    Dravere schrieb:

    ...
    std::stack ist ja nur ein Adapter, welcher die Aufrufe direkt an den Container weiterleitet. ...

    Muss er nicht.
    Hier gehst Du wieder von einer bestimmten Implementation aus und nicht vom zugrundeliegenden Konzept (und "Stack" ist genaugenommen erstmal nur ein Konzept).

    Dravere schrieb:

    ...
    Das haben ich jetzt schon zigg tausend Male gehört, dabei noch gar nie behauptet!...

    Doch - genau das behauptest Du ständig (wenn auch implizit) mit der Frage, warum stack kein "clear()" hat (bzw. der Forderung, es müsse doch eines haben) und mit Deinem "clear-Nachbau-Ansatz".

    Gruß,

    Simon2.



  • clear fehlt weil designfehler. so einfach ist das.



  • Shade Of Mine schrieb:

    clear fehlt weil designfehler. so einfach ist das.

    Denk ich auch. Wäre mal interessant, ob die die behaupten, dass es dafür einen Grund gibt auch eine offizielle Quelle dazu haben.



  • Shade Of Mine schrieb:

    clear fehlt weil designfehler. so einfach ist das.

    Quelle ?

    Gruß,

    Simon2.


  • Administrator

    @Simon2,
    Ich glaube du verstehst da was falsch. Ich sage nur, dass man einen Stack leeren kann. Wieso nicht eine optimierte Methode dafür anbieten?
    Egal was dieses leeren ist, die Eigenschaft besteht.

    Simon2 schrieb:

    Dravere schrieb:

    ...
    std::stack ist ja nur ein Adapter, welcher die Aufrufe direkt an den Container weiterleitet. ...

    Muss er nicht.
    Hier gehst Du wieder von einer bestimmten Implementation aus und nicht vom zugrundeliegenden Konzept (und "Stack" ist genaugenommen erstmal nur ein Konzept).

    Ich weiss nur, dass es in der Dinkumware StdLib so implementiert ist und es macht auch nicht all zu viel anders Sinn. Das Konzept vom Stack besteht darin, dass ein Container genommen wird und zum Beispiel bei top beim zugrunde liegenden Container back() aufruft.
    Wieso also nicht auch ein clear() , welches zu einem clear() vom Container weitergeleitet wird?

    Simon2 schrieb:

    Doch - genau das behauptest Du ständig (wenn auch implizit) mit der Frage, warum stack kein "clear()" hat (bzw. der Forderung, es müsse doch eines haben) und mit Deinem "clear-Nachbau-Ansatz".

    Nein, eben nicht. Ich verlange, dass stack als Konzept das clear unterstützen sollte.

    Stell dir am besten vor, dass std::stack kein top() hätte und ich verlange nun ein top() , da dies ja typisch für einen Stack ist. Es läuft auf das genau gleiche hinaus, einfach top() mit clear() ersetzen.

    @Shade Of Mine,
    So sehe ich das derzeit. Aber ich frage mich halt, ob es wirklich ein Designfehler war, oder ob man es weggelassen hat, aus den gleichen sinnlosen Gründen, wie hier genannt wurden. Oder doch einen sinnvollen Grund?
    Aber eigentlich ist es ja auch egal. Ich find es nur extrem schade.
    Wird das vielleicht im C++0x Standard geändert?

    Grüssli



  • Shade Of Mine schrieb:

    clear fehlt weil designfehler. so einfach ist das.

    oder: "Das clear bei Containern ist ein Designfehler; und beim Stack hat man's gemerkt". Beweis: es gibt einen Destruktor.

    Ich finde clear() bei Containern genauso überflüssig wie close() bei fstream. Letztlich hat immer der Destruktor den Job, hinterher alles aufzuräumen, was noch übrig bleibt.

    Dravere schrieb:

    Aber irgendwann ist die Aufgabe beendet und der Stack ist bei mir dann nicht zwingend leer, muss er auch nicht sein. Wenn die Aufgabe aber wieder von vorne beginnen soll, mit dem gleichen Objekt, dann muss der Stack leer sein. Also brauche ich ein clear, welches mir garantiert, das der Stack leer ist, nach dessen aufruf.

    braucht man eben nicht, wenn die 'Aufgabe' in einem Scope passiert und das 'Arbeitsobjekt' - in diesem Fall der Stack - nicht außerhalb sondern eben innerhalb des Scopes angelegt wird. Das Anlegen eines (leeren) Containers oder Stacks ist im Allgemeinen mit mehr oder weniger keinem Aufwand verbunden. Der Code wird dadurch klarer (Stack existiert nur im Scope) und kürzer (clear unnötig) und robuster, weil mit jedem Verlassen des Scopes im Fehlerfall oder sonstwie (z.B. Exception) wird automatisch aufgeräumt.

    Gruß
    Werner



  • Dravere schrieb:

    ...Das Konzept vom Stack besteht darin, dass ein Container genommen wird und zum Beispiel bei top beim zugrunde liegenden Container back() aufruft....

    Du kannst es gerne noch auf 20 weitere Arten neu schreiben, es wird dadurch nicht richtiger. Du beschreibst eine Implementierungsmöglichkeit von "Stack".
    Aber das "Konzept" von Stack lautet einfach: "Ich kann Dinge sukkzessive drauflegen und wieder herunternehmen".

    Gruß,

    Simon2.



  • Werner Salomon schrieb:

    Shade Of Mine schrieb:

    clear fehlt weil designfehler. so einfach ist das.

    oder: "Das clear bei Containern ist ein Designfehler; und beim Stack hat man's gemerkt". Beweis: es gibt einen Destruktor.

    Ich finde clear() bei Containern genauso überflüssig wie close() bei fstream. Letztlich hat immer der Destruktor den Job, hinterher alles aufzuräumen, was noch übrig bleibt.

    Also nen filestream kannst du wohl nicht mit nem Container vergleichen. Wieso sollte man den nen Container nie leeren müssen? Das ist doch Quatsch, dass ich immer nen neuen erzeugen muss, nur weil ich ihn leeren will. Und es gibt auch Container die länger als nur einen Funktionsaufruf gültig sind. Wenn du z.B. nen Undo und nen Redo Stack hast und den Redo Stack immer dann leeren willst, wenn was neues in den Undo Stack kommt, meinst du dass man dann immer delete und new machen sollte?



  • Werner Salomon schrieb:

    Ich finde clear() bei Containern genauso überflüssig wie close() bei fstream. Letztlich hat immer der Destruktor den Job, hinterher alles aufzuräumen, was noch übrig bleibt.

    clear räumt nicht auf, clear zerstört nur alle objekte. das ist grundverschieden zu einem close() oder dtor...

    deshalb gibt es ja für wirkliches resetten eines containers den swap trick.


  • Administrator

    Simon2 schrieb:

    Aber das "Konzept" von Stack lautet einfach: "Ich kann Dinge sukkzessive drauflegen und wieder herunternehmen".

    Ok, gehen wir es anders an. Und wer definiert das? Nur weil es mal ein Hans Jockel irgendwas so definiert hat, sollte man es auch immer so umsetzen, obwohl es völlig unpraktisch ist?
    Nach meiner Definition kann ein Stack auch ein clear aufweisen. Es gibt keinen Grund, wieso man einen Stack nicht leeren dürfen sollte. Wenn du dich unbedingt an die Theorien von irgendeiner Person halten möchtest, bitte sehr! Allerdings finde ich das ein wenig blind oder sturr.

    @Werner Salomon,
    Grundsätzlich wurde das meiste schon gesagt, aber etwas möchte ich noch dazufügen. Wieso willst du immer wieder neue Objekte anlegen, wenn du das gleiche wiederverwenden kannst?

    Grüssli



  • jojoe schrieb:

    Wenn du z.B. nen Undo und nen Redo Stack hast und den Redo Stack immer dann leeren willst, wenn was neues in den Undo Stack kommt, meinst du dass man dann immer delete und new machen sollte?

    ok - diese Beispiel gibt mir zu denken. Ich persönlich habe noch nie ein clear() bei Containern benötigt.

    Laut Standard ist der Container als Member im std::stack protected und heißt immer 'c'. Man kann sich also leicht die gewünschte Add-In-Funktionalität selber basteln:

    template< typename T, typename C = std::deque< T > >
    class Stack_with_clear : public std::stack< T, C >
    {
    public:
        void clear()
        {
            this->c.clear();
        }
    };
    

    Gruß
    Werner



  • Dravere schrieb:

    Grundsätzlich wurde das meiste schon gesagt, aber etwas möchte ich noch dazufügen. Wieso willst du immer wieder neue Objekte anlegen, wenn du das gleiche wiederverwenden kannst?

    Naja - ich will eben nicht das selbe verwenden. Wenn ich die von Dir beschriebene Aufgabe ausführen will, zu der ich den Stack benötige, dann beginne ich mit einem 'frischen' Stack-Objekt. Damit habe ich garantiert gleiche Startbedingungen und habe sicher keine Seiteneffekte von vorherigen Durchläufen. Ich habe schon das eine oder andere Mal Fehler aus Programmen rausmachen können, wo genau so etwas passiert ist.

    Gruß
    Werner



  • #InDenRaumWerf

    evtl war die idee dahinter
    - alles was in einem stack gepackt wird soll auch wieder heraus genommen werden
    - neue aufgaben = neuen stack
    - stack leeren bedeutet aufgaben verwerfen und einen neuen stack starten - da sollte gleich ein neuer stack gebaut werden

    nur so ideen


  • Administrator

    Werner Salomon schrieb:

    Naja - ich will eben nicht das selbe verwenden. Wenn ich die von Dir beschriebene Aufgabe ausführen will, zu der ich den Stack benötige, dann beginne ich mit einem 'frischen' Stack-Objekt. Damit habe ich garantiert gleiche Startbedingungen und habe sicher keine Seiteneffekte von vorherigen Durchläufen. Ich habe schon das eine oder andere Mal Fehler aus Programmen rausmachen können, wo genau so etwas passiert ist.

    Kann man das auch so interpretieren, dass du deinem Computer, bzw. der Bibliothek nicht vertraust? Dann kann ich aber fast mit Sicherheit garantieren, dass du schlechteren Code schreiben wirst. Überflüssige If-Abfragen und anderes sind dann schnell auch üblich, da man wirklich "sicher sicher" sein möchte.

    Mr Evil schrieb:

    #InDenRaumWerf

    Immer diese Leute mit den Präprozessor anweisungen. 🙂

    Mr Evil schrieb:

    - alles was in einem stack gepackt wird soll auch wieder heraus genommen werden

    Ist bei einem clear gewährleistet.

    Mr Evil schrieb:

    - neue aufgaben = neuen stack

    Wieso kann man das gleiche Objekt nicht wiederverwenden? Wird doch oft auch getan und erscheint auch sinnvoll zu sein.

    Mr Evil schrieb:

    - stack leeren bedeutet aufgaben verwerfen und einen neuen stack starten - da sollte gleich ein neuer stack gebaut werden

    Und wieso gleich einen neuen? Wozu der Unterschied? Wieso der zusätzliche Aufwand? Wieso nicht gleich das gleiche Objekt wiederverwenden? Das macht doch überhaupt gar keinen Sinn.

    Grüssli


Anmelden zum Antworten