Container der C++-Standardbibliothek

Die Standardbibliothek stellt unterschiedliche typsichere Container zum Speichern verknüpfter Objekte bereit. Die Container sind Klassenvorlagen. Wenn Sie eine Containervariable deklarieren, geben Sie den Typ der Elemente an, die der Container enthält. Container können mit Initialisiererlisten erstellt werden. Sie verfügen über Memberfunktionen zum Hinzufügen und Entfernen von Elementen und zum Ausführen anderer Vorgänge.

Mit Iteratoren können Sie die einzelnen Elemente in einem Container durchlaufen und darauf zugreifen. Sie können Iteratoren explizit verwenden, indem Sie ihre Memberfunktionen und Operatoren und globalen Funktionen verwenden. Sie können sie auch implizit verwenden, z. B. mit einer range-for-Schleife. Iteratoren für alle C++-Standardbibliothekscontainer haben eine gemeinsame Schnittstelle, aber jeder Container definiert seine eigenen speziellen Iteratoren.

Container können in drei Kategorien unterteilt werden: Sequenzcontainer, assoziative Container und Containeradapter.

Sequenzcontainer

Sequenzcontainer wahren die Reihenfolge der von Ihnen angegebenen eingefügten Elemente.

Ein vector-Container verhält sich wie ein Array, kann jedoch nach Bedarf automatisch erweitert werden. Er wird mit direktem Zugriff bzw. zusammenhängend gespeichert, und ist in der Länge hochgradig flexibel. Aus diesen und weiteren Gründen ist vector der bevorzugte Sequenzcontainer für die meisten Anwendungen. Verwenden Sie einen Vektor, wenn Sie sich nicht sicher sind, welchen Sequenzcontainertyp Sie verwenden sollen. Weitere Informationen finden Sie unter vector "Klasse".

Ein array Container hat einige der Stärken von vector, aber die Länge ist nicht so flexibel. Weitere Informationen finden Sie unter array "Klasse".

Ein deque-Container (doppelseitige Warteschlange) ermöglichen schnelles Einfügen und Löschen am Anfang und Ende des Containers. Sie teilt die Vorteile des zufälligen Zugriffs und der flexiblen Länge von vector, ist aber nicht zusammenhängend. Weitere Informationen finden Sie unter deque "Klasse".

Ein list Container ist eine doubly verknüpfte Liste, die bidirektionalen Zugriff, schnelle Einfügungen und schnelle Löschungen überall im Container ermöglicht, aber Sie können nicht zufällig auf ein Element im Container zugreifen. Weitere Informationen finden Sie unter list "Klasse".

Ein forward_list-Container ist eine einfach verknüpfte Liste. Er ist die Version mit Vorwärtszugriff von list. Weitere Informationen finden Sie unter forward_list "Klasse".

Assoziative Container

In assoziativen Containern werden Elemente in einer vordefinierten Reihenfolge eingefügt, z. B. sortiert aufsteigend. Unsortierte assoziative Container sind ebenfalls verfügbar. Assoziative Container können in zwei Teilbereiche gruppiert werden: Zuordnungen und Sätze.

map (manchmal auch als ein Wörterbuch bezeichnet) besteht aus einem Schlüssel-Wert-Paar. Der Schlüssel wird zum Sortieren der Reihenfolge verwendet, und der Wert wird dem Schlüssel zugeordnet. Z. B. kann map eindeutige Schlüssel enthalten, die jedes einzelne Wort in einem Text und die entsprechenden Werte darstellen, die die Häufigkeit darstellen, mit der jedes Wort im Text angezeigt wird. Die unsortierte Version von map ist unordered_map. Weitere Informationen finden Sie unter map "Klasse " und unordered_map "Klasse".

Ein set-Element ist lediglich ein aufsteigender Container eindeutiger Elemente. Der Wert ist auch gleichzeitig der Schlüssel. Die unsortierte Version von set ist unordered_set. Weitere Informationen finden Sie unter set "Klasse " und unordered_set "Klasse".

Sowohl map als auch set ermöglichen das Einfügen nur einer Instanz eines Schlüssels oder Elements in den Container. Wenn mehrere Instanzen der Elemente erforderlich sind, verwenden Sie multimap oder multiset. Die unsortierten Versionen sind unordered_multimap und unordered_multiset. Weitere Informationen finden Sie unter multimap "Klasse",unordered_multimap "Klasse",multiset "Klasse" und unordered_multiset "Klasse".

Bei sortierten Zuordnungen und Sätzen werden bidirektionale Iteratoren unterstützt, und bei den unsortierten Entsprechungen werden Vorwärtsiteratoren unterstützt. Weitere Informationen finden Sie unter Iteratoren.

Heterogenes Nachschlagen in assoziativen Containern (C++14)

Die sortierten assoziativen Container (Zuordnung, Multimap, Satz und Multiset) unterstützen jetzt heterogene Suche, was bedeutet, dass Sie nicht mehr den genauen Objekttyp wie den Schlüssel oder das Element in Memberfunktionen wie find() und lower_bound(). Stattdessen können Sie einen beliebigen Typ übergeben, für den ein überladener operator< definiert ist, mit dem ein Vergleich mit dem Schlüsseltyp aktiviert wird.

Die heterogene Suche ist auf Opt-In-Basis aktiviert, wenn Sie beim Deklarieren der Containervariablen den std::less<> Vergleichs- oder std::greater<> "Diamant-Functor" angeben, wie hier gezeigt:

std::set<BigObject, std::less<>> myNewSet;

Bei Verwendung des Standardvergleichsoperators weist der Container dasselbe Verhalten wie in C++11 und früheren Versionen auf.

Im folgenden Beispiel wird gezeigt, wie Benutzer eines std::set Nachschlagevorgangs überladen operator< werden können, indem sie einfach eine kleine Zeichenfolge übergeben, die mit dem Element jedes BigObject::id Objekts verglichen werden kann.

#include <set>
#include <string>
#include <iostream>
#include <functional>

using namespace std;

class BigObject
{
public:
    string id;
    explicit BigObject(const string& s) : id(s) {}
    bool operator< (const BigObject& other) const
    {
        return this->id < other.id;
    }

    // Other members....
};

inline bool operator<(const string& otherId, const BigObject& obj)
{
    return otherId < obj.id;
}

inline bool operator<(const BigObject& obj, const string& otherId)
{
    return obj.id < otherId;
}

int main()
{
    // Use C++14 brace-init syntax to invoke BigObject(string).
    // The s suffix invokes string ctor. It is a C++14 user-defined
    // literal defined in <string>
    BigObject b1{ "42F"s };
    BigObject b2{ "52F"s };
    BigObject b3{ "62F"s };
    set<BigObject, less<>> myNewSet; // C++14
    myNewSet.insert(b1);
    myNewSet.insert(b2);
    myNewSet.insert(b3);
    auto it = myNewSet.find(string("62F"));
    if (it != myNewSet.end())
        cout << "myNewSet element = " << it->id << endl;
    else
        cout << "element not found " << endl;

    // Keep console open in debug mode:
    cout << endl << "Press Enter to exit.";
    string s;
    getline(cin, s);
    return 0;
}

//Output: myNewSet element = 62F

Die folgenden Memberfunktionen in Zuordnung, Multimap, Set und Multiset wurden überladen, um heterogene Suche zu unterstützen:

  1. find

  2. count

  3. lower_bound

  4. upper_bound

  5. equal_range

Containeradapter

Ein Containeradapter ist die Variante einer Sequenz oder eines assoziativen Containers, die die Schnittstelle zwecks Einfachheit und Verständlichkeit einschränkt. Containeradapter unterstützen iteratoren nicht.

Ein queue-Container folgt der FIFO-Semantik (first in, first out). Das erste abgelegte Element, d.h. das in Warteschlange eingefügte, ist das erste, das entnommen wird, d.h. aus der Warteschlange entfernt wird. Weitere Informationen finden Sie unter queue "Klasse".

Ein priority_queue-Container wird so organisiert, dass das Element, das über den höchsten Wert verfügt, immer zuerst in der Warteschlange steht. Weitere Informationen finden Sie unter priority_queue "Klasse".

Ein stack-Container folgt der LIFO-Semantik (last in, first out). Das letzte Element, das auf dem Stapel abgelegt wird, ist das erste entnommene Element. Weitere Informationen finden Sie unter stack "Klasse".

Da Containeradapter iteratoren nicht unterstützen, können sie nicht mit den C++-Standardbibliotheksalgorithmen verwendet werden. Weitere Informationen finden Sie unter Algorithmen.

Anforderungen für Containerelemente

Im Allgemeinen können Elemente, die in einen C++-Standardbibliothekscontainer eingefügt werden, fast jeden Objekttyp haben, wenn sie kopiert werden können. Nur verschiebbare Elemente – z. B. vector<unique_ptr<T>>, die mithilfe von unique_ptr<> erstellt werden, funktionieren, solange keine Memberfunktionen aufgerufen werden, die versuchen, sie zu kopieren.

Der Destruktor darf keine Ausnahme auslösen.

Sortierte assoziative Container (früher im Artikel beschrieben) müssen einen öffentlich definierten Vergleichsoperator aufweisen. Standardmäßig ist operator<der Operator , aber auch Typen, die operator< nicht funktionieren, werden unterstützt.

Einige Vorgänge in Containern könnten auch einen öffentlichen Standardkonstruktor und einen öffentlichen Äquivalenzoperator erfordern. Beispielsweise benötigen die unsortierten assoziativen Container eine Unterstützung für Gleichheit und Hashverfahren.

Zugreifen auf Containerelemente

Auf Containerelemente wird mithilfe von Iteratoren zugegriffen. Weitere Informationen finden Sie unter Iteratoren.

Hinweis

Sie können auch bereichsbasierte For-Schleifen verwenden, um C++-Standardbibliotheksauflistungen zu durchlaufen.

Vergleichen von Containern

Alle Container überladen den Operator „==“ zum Vergleichen von zwei Containern desselben Typs, die den gleichen Elementtyp aufweisen. Sie können == verwenden, um eine Vektorzeichenfolge mit einer anderen<Vektorzeichenfolge> zu vergleichen, aber Sie können sie nicht verwenden, um eine Vektorzeichenfolge mit einer Listenzeichenfolge<> oder einer Vektorzeichenfolge>> mit einem<Vektorzeichen<<*> zu vergleichen.<> In C++98/03 können Sie unterschiedlichen Containertypen und/oder Elementtypen verwenden std::equal oder std::mismatch vergleichen. In C++11 können Sie auch verwenden std::is_permutation. In all diesen Fällen gehen die Funktionen jedoch davon aus, dass die Container dieselbe Länge haben. Wenn der zweite Bereich kürzer als der erste ist, kommt es zu nicht definiertem Verhalten. Wenn der zweite Bereich länger ist, sind die Ergebnisse möglicherweise trotzdem falsch, da der Vergleich nie über das Ende des ersten Bereichs hinaus fortgesetzt wird.

Vergleichen unterschiedlicher Container (C++14)

In C++14 und höher können Sie unterschiedliche Container und/oder nicht unterschiedliche Elementtypen vergleichen, indem Sie eine der std::equalÜberladungen , std::mismatchoder std::is_permutation Funktionsüberladungen verwenden, die zwei vollständige Bereiche verwenden. Mit diesen Überladungen können Sie Container mit unterschiedlicher Länge vergleichen. Diese Überladungen sind weniger für Benutzerfehler anfällig und sind beim Vergleichen von Containern mit unterschiedlicher Länge so optimiert, dass sie in konstanter Zeit FALSE zurückgeben. Daher empfehlen wir Ihnen, diese Überladungen zu verwenden, es sei denn, Sie haben einen klaren Grund, nicht zu verwenden, oder Sie verwenden einen std::list Container, der nicht von den Optimierungen der dualen Reichweite profitiert.

Siehe auch

Parallele Container
<sample container>
Threadsicherheit in der C++-Standardbibliothek