Übersicht STL Container



  • Ich bin kein aktiver C++ Programmerer und vergesse daher immer wieder wie sich die einzelnen Container unterscheiden.

    Gibt es nicht irgendwo so interaktive Auswahlhilfe?

    Sollte ungefähr so aussehen:

    (muss jetzt nicht stimmen)
    Sortiert - in eine beide Richtungen Iterierbar -> set
    Ein primary key, ein value, sortiert, in beide richtungen Iterierbar -> map

    Besten Dank im Voraus



  • ja, so eine Grafik gibts, hab den Link aber gerade nicht parat. Kann ihn in ~3 Stunden nachliefern.

    greetz KN4CK3R


  • Mod

    Ja:
    http://stackoverflow.com/questions/10699265/how-can-i-efficiently-select-a-standard-library-container-in-c11

    Das Bild am Anfang ist das Standardbild, welches immer gezeigt wird, es vermittelt auf den ersten Blick den falschen Eindruck, dass alle Container in der Praxis gleich häufig vorkommen. Dein Container erster Wahl sollte vector sein, erst wenn dieser nicht passt, guckst du anderswo. Lies dir in dem Link die ersten paar Antworten durch, die erklären das viel ausführlicher.



  • SeppJ schrieb:

    Ja:
    http://stackoverflow.com/questions/10699265/how-can-i-efficiently-select-a-standard-library-container-in-c11

    Das Bild am Anfang ist das Standardbild, welches immer gezeigt wird, es vermittelt auf den ersten Blick den falschen Eindruck, dass alle Container in der Praxis gleich häufig vorkommen. Dein Container erster Wahl sollte vector sein, erst wenn dieser nicht passt, guckst du anderswo. Lies dir in dem Link die ersten paar Antworten durch, die erklären das viel ausführlicher.

    Geil, das ist genau das wonach ich den ganzen Vormittag gesucht habe. Danke

    Ich dachte eigenetlich immer dass ich meinen Container so wählen sollte, dass er das Minimum an Funktionen hat? Vector hat ja nahezu alles.


  • Mod

    solala schrieb:

    Vector hat ja nahezu alles.

    Alles? 😕 Er kann hinten wachsen und hat wahlfreien Zugriff. Minimaler wäre nur std::array, welches nur wahlfreien Zugriff hat, aber nicht wachsen kann. Was wünscht du dir denn noch weniger?



  • SeppJ schrieb:

    solala schrieb:

    Vector hat ja nahezu alles.

    Alles? 😕 Er kann hinten wachsen und hat wahlfreien Zugriff. Minimaler wäre nur std::array, welches nur wahlfreien Zugriff hat, aber nicht wachsen kann. Was wünscht du dir denn noch weniger?

    😃 Da sieht man mal wieder wie nötig ich dieses Flussdiagramm habe.



  • das Bild meinte ich, dann spar ich mir den Link

    greetz KN4CK3R



  • KN4CK3R schrieb:

    das Bild meinte, dann spar ich mir den Link

    greetz KN4CK3R

    Jou, danke. Damit bin ich glücklich.



  • So richtig doll überlegen muss ich da eigentlich nicht. Es gibt ja nur zwei Klassen von Containern:

    • Sequenz-Container. Das sind vector , list , deque .
    • Assoziative Container. Das sind set , map , multimap , und ab C++11 noch die unodered_ -Varianten.

    Bei Sequenz-Containern lässt sich die Ordnung der Elemente vom Benutzer festlegen und ändern. Diesen Containern ist das egal, in welcher Reihenfolge die Elemente drin stehen. Die Reihenfolge bleibt aber so erhalten und hängt davon ab, wie der Benutzer die Elemente eingefügt hat.

    Bei assoziativen Containern geben die Container die Ordnung vor. Die Reihenfolge der Elemente ist entweder nach dem Schlüssel sortiert ( set , map , multimap ) oder eben pseudo-zufällig ( unordered_ * ab C++11) in Abhängigkeit einer Hash-Funktion.

    Alles andere ( stack , queue , priority_queue ) sind nur Adapter, die unter der Motorhaube einen der schon genannten Sequenz-Containern verwenden (jedenfalls per Default). Sie haben eine relativ minimale Schnittstelle und falls sie genau das anbieten, was man braucht, sollte man sie wohl auch benutzen.

    Braucht man einen Sequenz-Container mit einer mächtigeren Schnittstelle, steht man vor der Wahl zwischen vector , deque und list . Nach Stroustrup, sollte man im Zweifel einfach vector verwenden. deque wird interessant, wenn man auch am Anfang Elemente hinzufügen oder löschen können will und list<T> wird interessant, wenn der Aufwand, ein T-Objekt von einem Speicherort zu einem anderen zu bewegen, sehr groß ist und man gar kein "random access" benötigt.

    Braucht man einen assoziativen Container hat man die Wahl zwischen den "sortierten" und den "unsortierten". Wenn man auf die sortierte Reihenfolge verzichten kann und man schon auf eine gute Hashfunktion zurückgreifen kann, würde ich die unordered_ *-Container empfehlen. Sonst einfach die "sortierten". Ob es dann ein set , eine map oder eine multimap wird, hängt ja davon ab, was man damit machen will. set heißt so, weil es sich an eine mathematische Menge anlehnt. Bei map ist das ähnlich, es speichert eindeutige Zuordnungen wohingegen eine multimap einen "Schlüssel" mit mehreren "Werten" verknüpfen kann.

    Hmm ... der Text ist doch länger geworden, als eigentlich gedacht ...
    Ist wohl doch nicht ganz so trivial.



  • krümelkacker schrieb:

    So richtig doll überlegen muss ich da eigentlich nicht. Es gibt ja nur zwei Klassen von Containern:

    • Sequenz-Container. Das sind vector , list , deque .
    • Assoziative Container. Das sind set , map , multimap , und ab C++11 noch die unodered_ -Varianten.

    Bei Sequenz-Containern lässt sich die Ordnung der Elemente vom Benutzer festlegen und ändern. Diesen Containern ist das egal, in welcher Ordnung die Elemente drin stehen. Die Ordnung bleibt so erhalten, wie der Benutzer die Elemente hinzufügt.

    Bei assoziativen Containern geben die Container die Ordnung vor. Die Reihenfolge der Elemente ist entweder nach dem Schlüssel sortiert ( set , map , multimap ) oder eben pseudo-zufällig ( unordered_ * ab C++11) in Abhängigkeit einer Hash-Funktion.

    Alles andere ( stack , queue , priority_queue ) sind nur Adapter, die unter der Motorhaube einen der schon genannten Sequenz-Containern verwenden (jedenfalls per Default). Sie haben eine relativ minimale Schnittstelle und falls sie genau das anbieten, was man braucht, sollte man sie wohl auch benutzen.

    Braucht man einen Sequenz-Container mit einer mächtigeren Schnittstelle, steht man vor der Wahl zwischen vector , deque und list . Nach Stroustrup, sollte man im Zweifel einfach vector verwenden. deque wird interessant, wenn man auch am Anfang Elemente hinzufügen oder löschen können will und list<T> wird interessant, wenn der Aufwand, ein T-Objekt von einem Speicherort zu einem anderen zu bewegen, sehr groß ist und man gar kein "random access" benötigt.

    Braucht man einen assoziativen Container hat man die Wahl zwischen den "normalen" und den "ungeordneten". Wenn man auf die sortierte Reihenfolge verzichten kann und man schon auf eine gute Hashfunktion zurückgreifen kann, würde ich die unordered_ *-Container empfehlen. Sonst einfach die "normalen". Ob es dann ein set , eine map oder eine multimap wird, hängt ja davon ab, was man damit machen will. set heißt so, weil es sich an eine mathematische Menge anlehnt. Bei map ist das ähnlich, es speichert eindeutige Zuordnungen wohingegen eine multimap einen "Schlüssel" mit mehreren "Werten" verknüpfen kann.

    Hmm ... der Text ist doch länger geworden, als eigentlich gedacht ...
    Ist wohl doch nicht ganz so trivial.

    Ob lang oder nicht, wurde aber als Info aufgenommen. Danke


Anmelden zum Antworten