
Daniel Schluff
Ich habe mich in meinem Buch über C++ über STL-Container informiert, insbesondere im Abschnitt über die STL und ihre Container. Jetzt verstehe ich, dass jeder einzelne von ihnen seine eigenen spezifischen Eigenschaften hat, und ich bin kurz davor, sie alle auswendig zu lernen … Aber was ich noch nicht verstehe, ist, in welchem Szenario jeder von ihnen verwendet wird.
Was ist die Erklärung? Beispielcode wird viel bevorzugt.

zdan
Dieser Spickzettel bietet eine ziemlich gute Zusammenfassung der verschiedenen Container.
Sehen Sie sich das Flussdiagramm unten als Leitfaden für die Verwendung in verschiedenen Nutzungsszenarien an:

Erstellt von David Moore und lizensiert CC BY-SA 3.0
Hier ist ein Flussdiagramm, das von David Moores Version (siehe oben) inspiriert wurde, die ich erstellt habe und die (größtenteils) auf dem neuesten Stand des neuen Standards (C++11) ist. Dies ist nur meine persönliche Meinung dazu, es ist nicht unbestreitbar, aber ich dachte, es könnte für diese Diskussion wertvoll sein:


David Thornley
Einfache Antwort: verwenden std::vector
für alles, es sei denn, Sie haben einen echten Grund, etwas anderes zu tun.
Wenn Sie einen Fall finden, bei dem Sie denken: “Mensch, std::vector
funktioniert hier wegen X nicht gut”, gehen Sie von X aus.
Sehen Sie sich Effektive STL von Scott Meyers an. Es ist gut zu erklären, wie man die STL verwendet.
Wenn Sie eine bestimmte/unbestimmte Anzahl von Objekten speichern möchten und niemals eines löschen werden, dann ist ein Vektor genau das Richtige für Sie. Es ist der Standardersatz für ein C-Array und funktioniert wie eines, läuft aber nicht über. Sie können seine Größe auch vorher mit reserve() festlegen.
Wenn Sie eine unbestimmte Anzahl von Objekten speichern möchten, diese aber hinzufügen und löschen, möchten Sie wahrscheinlich eine Liste … weil Sie ein Element löschen können, ohne nachfolgende Elemente zu verschieben – im Gegensatz zu Vektoren. Es benötigt jedoch mehr Speicher als ein Vektor, und Sie können nicht sequentiell auf ein Element zugreifen.
Wenn Sie eine Reihe von Elementen nehmen und nur die eindeutigen Werte dieser Elemente finden möchten, können Sie sie alle in einen Satz einlesen und sie auch für Sie sortieren.
Wenn Sie viele Schlüssel-Wert-Paare haben und diese nach Schlüssel sortieren möchten, ist eine Zuordnung nützlich … aber sie enthält nur einen Wert pro Schlüssel. Wenn Sie mehr als einen Wert pro Schlüssel benötigen, können Sie einen Vektor/eine Liste als Wert in der Karte haben oder eine Multimap verwenden.
Es ist nicht in der STL, aber es ist im TR1-Update der STL: Wenn Sie viele Schlüssel-Wert-Paare haben, die Sie nach Schlüsseln suchen, und Sie sich nicht um ihre Reihenfolge kümmern, können Sie dies tun einen Hash verwenden möchten – das ist tr1::unordered_map. Ich habe es mit Visual C++ 7.1 verwendet, wo es stdext::hash_map hieß. Es hat eine Suche nach O (1) anstelle einer Suche nach O (log n) für map.

Ebrahim
Ich habe das Flussdiagramm so umgestaltet, dass es 3 Eigenschaften hat:
- Ich denke, STL-Container sind in zwei Hauptklassen unterteilt. Die Basiscontainer und diese nutzen die Basiscontainer, um eine Richtlinie zu implementieren.
- Zunächst sollte das Flussdiagramm den Entscheidungsprozess in die Hauptsituationen unterteilen, über die wir entscheiden sollten, und dann jeden Fall näher erläutern.
- Bei einigen erweiterten Containern besteht die Möglichkeit, einen anderen Basiscontainer als Innencontainer zu wählen. Das Flussdiagramm sollte die Situationen berücksichtigen, in denen jeder der Basisbehälter verwendet werden kann.
Das Flussdiagramm: 
Weitere Informationen finden Sie in dieser Link.

Peter Mortensen
Ein wichtiger Punkt, der bisher nur kurz erwähnt wurde, ist, dass Sie, wenn Sie zusammenhängenden Speicher benötigen (wie es ein C-Array gibt), nur verwenden können vector
, array
oder string
.
Verwenden array
wenn die Größe zur Kompilierzeit bekannt ist.
Verwenden string
wenn Sie nur mit Zeichentypen arbeiten müssen und eine Zeichenfolge benötigen, nicht nur einen Allzweckcontainer.
Verwenden vector
in allen anderen Fällen (vector
sollte in den meisten Fällen ohnehin die Standardwahl für Container sein).
Mit allen dreien können Sie die verwenden data()
Member-Funktion, um einen Zeiger auf das erste Element des Containers zu erhalten.

Gebote
Es hängt alles davon ab, was Sie lagern möchten und was Sie mit dem Container machen möchten. Hier sind einige (sehr nicht erschöpfende) Beispiele für die Containerklassen, die ich am häufigsten verwende:
vector
: Kompaktes Layout mit wenig oder keinem Speicheraufwand pro enthaltenem Objekt. Effizient zu iterieren. Anhängen, Einfügen und Löschen können teuer sein, insbesondere bei komplexen Objekten. Günstig ein enthaltenes Objekt per Index zu finden, zB myVector[10]. Verwenden Sie es dort, wo Sie in C ein Array verwendet hätten. Gut, wenn Sie viele einfache Objekte haben (z. B. int). Verwendung nicht vergessen reserve()
bevor Sie dem Container viele Objekte hinzufügen.
list
: Geringer Speicheraufwand pro enthaltenem Objekt. Effizient zu iterieren. Anhängen, Einfügen und Löschen sind billig. Verwenden Sie dort, wo Sie in C eine verkettete Liste verwendet hätten.
set
(und multiset
): Erheblicher Speicheraufwand pro enthaltenem Objekt. Verwenden Sie es dort, wo Sie schnell herausfinden müssen, ob dieser Container ein bestimmtes Objekt enthält, oder Container effizient zusammenführen.
map
(und multimap
): Erheblicher Speicheraufwand pro enthaltenem Objekt. Verwenden Sie, wo Sie Schlüssel-Wert-Paare speichern und Werte schnell nach Schlüssel suchen möchten.
Das Flussdiagramm auf der Spickzettel vorgeschlagen von zdan bietet eine umfassendere Anleitung.
9984600cookie-checkIn welchem Szenario verwende ich einen bestimmten STL-Container?yes
meinst du map, vectot, set etc?
– Thomas Tempelmann
23. Januar 2009 um 0:35 Uhr
Selbst wenn ich mir dieses Diagramm anschaue, kann ich nicht sagen, welches das beste für meine Frage wäre stackoverflow.com/questions/9329011/…
– sergiol
24. Februar 2012 um 19:32 Uhr
Ich habe eine erstellt Bearbeitbare Version von Mikaels C++ Container Cheat Sheet. Dies ist der Spickzettel von @MikaelPersson. Leider kann ich unter seiner Antwort keinen Kommentar abgeben, da ich noch keinen 50-Ruf habe.
– Parker Schamblin
14. August 2020 um 19:53 Uhr