Delen via


C++ Standaardbibliotheekcontainers

De Standaardbibliotheek biedt verschillende typeveilige containers voor het opslaan van verzamelingen gerelateerde objecten. De containers zijn klassesjablonen. Wanneer u een containervariabele declareert, geeft u het type op van de elementen die door de container worden opgeslagen. Containers kunnen worden samengesteld met initialisatielijsten. Ze hebben lidfuncties voor het toevoegen en verwijderen van elementen en het uitvoeren van andere bewerkingen.

U kunt de elementen in een container herhalen en de afzonderlijke elementen openen met behulp van iterators. U kunt iterators expliciet gebruiken met behulp van hun lidfuncties en operators en globale functies. U kunt ze ook impliciet gebruiken, bijvoorbeeld met behulp van een bereik-voor-lus. Iterators voor alle C++ Standard Library-containers hebben een gemeenschappelijke interface, maar elke container definieert zijn eigen gespecialiseerde iterators.

Containers kunnen worden onderverdeeld in drie categorieën: reekscontainers, associatieve containers en containeradapters.

Reekscontainers

Volgordecontainers behouden de volgorde van ingevoegde elementen die u opgeeft.

Een vector container gedraagt zich als een matrix, maar kan automatisch groeien als vereist. Het is willekeurige toegang en aaneengesloten opgeslagen, en lengte is zeer flexibel. Om deze redenen en meer is vector de voorkeursvolgordecontainer voor de meeste toepassingen. Wanneer u twijfelt over wat voor soort reekscontainer moet worden gebruikt, begint u met behulp van een vector! Zie vector Classvoor meer informatie.

Een array container heeft een aantal sterke punten, vectormaar de lengte is niet zo flexibel. Zie array Classvoor meer informatie.

Een deque (dubbel beëindigde wachtrij) container maakt snelle invoegingen en verwijderingen mogelijk aan het begin en einde van de container. Het deelt de voordelen van willekeurige toegang en flexibele lengte van vector, maar is niet aaneengesloten. Zie deque Classvoor meer informatie.

Een list container is een dubbel gekoppelde lijst waarmee bidirectionele toegang, snelle invoegingen en snelle verwijderingen overal in de container mogelijk zijn, maar u kunt geen willekeurig toegang krijgen tot een element in de container. Zie list Classvoor meer informatie.

Een forward_list container is een singly linked list , de forward-access-versie van list. Zie forward_list Classvoor meer informatie.

Associatieve containers

In associatieve containers worden elementen ingevoegd in een vooraf gedefinieerde volgorde, bijvoorbeeld als oplopend gesorteerd. Niet-geordende associatiecontainers zijn ook beschikbaar. De associatieve containers kunnen worden gegroepeerd in twee subsets: kaarten en sets.

Een map, ook wel een woordenlijst genoemd, bestaat uit een sleutel-waardepaar. De sleutel wordt gebruikt om de volgorde te orden en de waarde is gekoppeld aan die sleutel. Een kan bijvoorbeeld map sleutels bevatten die elk uniek woord in een tekst vertegenwoordigen en overeenkomende waarden die het aantal keren vertegenwoordigen dat elk woord in de tekst wordt weergegeven. De niet-geordende versie is mapunordered_map. Zie map Class en unordered_map Class voor meer informatie.

A set is slechts een oplopende container met unieke elementen. De waarde is ook de sleutel. De niet-geordende versie is setunordered_set. Zie set Class en unordered_set Class voor meer informatie.

Beide map en set slechts één exemplaar van een sleutel of element mogen worden ingevoegd in de container. Als er meerdere exemplaren van elementen vereist zijn, gebruikt multimap u of multiset. De niet-geordende versies zijn unordered_multimap en unordered_multiset. Zie multimap Class, unordered_multimap Class, multiset Class en Class voor unordered_multisetmeer informatie.

Geordende kaarten en sets ondersteunen bidirectionele iterators en hun niet-geordende tegenhangers ondersteunen doorstuurservers. Zie Iterators voor meer informatie.

Heterogene lookup in associatieve containers (C++14)

De geordende associatiecontainers (kaart, multimap, set en multiset) ondersteunen nu heterogene opzoekacties. Dit betekent dat u niet langer exact hetzelfde objecttype hoeft door te geven als de sleutel of het element in lidfuncties zoals find() en lower_bound(). In plaats daarvan kunt u elk type doorgeven waarvoor een overbelaste operator< is gedefinieerd die vergelijking met het sleuteltype mogelijk maakt.

Heterogene lookup is ingeschakeld op opt-in basis wanneer u de std::less<> of std::greater<> "diamond functor" comparator opgeeft bij het declareren van de containervariabele, zoals hier wordt weergegeven:

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

Als u de standaard comparator gebruikt, gedraagt de container zich precies zoals in C++11 en eerder.

In het volgende voorbeeld ziet u hoe u gebruikers van een operator< opzoekactie kunt laten overbelastingen std::set door een kleine tekenreeks door te geven die kan worden vergeleken met het lid van BigObject::id elk object.

#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

De volgende lidfuncties in kaart, multimap, set en multiset zijn overbelast om heterogene opzoekacties te ondersteunen:

  1. vinden

  2. aantal

  3. lower_bound

  4. upper_bound

  5. equal_range

Containeradapters

Een containeradapter is een variatie van een reeks of associatieve container die de interface voor eenvoud en duidelijkheid beperkt. Containeradapters bieden geen ondersteuning voor iterators.

Een queue container volgt FIFO-semantiek (eerst in, eerste uit). Het eerste element dat is gepusht( dat wil gezegd, ingevoegd in de wachtrij), is de eerste die moet worden weergegeven, dat wil gezegd, verwijderd uit de wachtrij. Zie queue Classvoor meer informatie.

Een priority_queue container is zodanig ingedeeld dat het element met de hoogste waarde altijd eerst in de wachtrij staat. Zie priority_queue Classvoor meer informatie.

Een stack container volgt lifo-semantiek (laatste in, eerste uit). Het laatste element dat op de stapel wordt gepusht, is het eerste element dat is gepopt. Zie stack Classvoor meer informatie.

Omdat containeradapters geen ondersteuning bieden voor iterators, kunnen ze niet worden gebruikt met de C++ Standard Library-algoritmen. Zie Algoritmen voor meer informatie.

Vereisten voor containerelementen

In het algemeen kunnen elementen die zijn ingevoegd in een C++ Standard Library-container ongeveer elk objecttype zijn als ze kunnen worden gekopieerd. Movable-only elementen, bijvoorbeeld die zoals vector<unique_ptr<T>> die worden gemaakt met behulp unique_ptr<> , werken zolang u geen lidfuncties aanroept die proberen ze te kopiëren.

De destructor is niet toegestaan om een uitzondering te genereren.

Geordende associatiecontainers, die eerder in dit artikel worden beschreven, moeten een openbare vergelijkingsoperator hebben gedefinieerd. De operator is operator<standaard, maar zelfs typen waarmee niet werkt operator< , worden ondersteund.

Voor sommige bewerkingen op containers is mogelijk ook een openbare standaardconstructor en een operator voor openbare gelijkwaardigheid vereist. De niet-geordende associatiecontainers vereisen bijvoorbeeld ondersteuning voor gelijkheid en hashing.

Toegang tot containerelementen

De elementen van containers worden geopend met behulp van iterators. Zie Iterators voor meer informatie.

Opmerking

U kunt ook op bereik gebaseerde lussen gebruiken om C++ Standard Library-verzamelingen te herhalen.

Containers vergelijken

Alle containers overbelasten de operator== voor het vergelijken van twee containers van hetzelfde type met hetzelfde elementtype. U kunt == gebruiken om een vectortekenreeks te vergelijken met een andere vectortekenreeks<, maar u kunt deze niet gebruiken om een vectortekenreeks><te vergelijken met een lijsttekenreeks><> of een vectortekenreeks<> met een vectortekenreeks<*.><> In C++98/03 kunt u verschillende containertypen en/of elementtypen vergelijken std::equal of std::mismatch vergelijken. In C++11 kunt u ook gebruiken std::is_permutation. Maar in al deze gevallen gaan de functies ervan uit dat de containers dezelfde lengte hebben. Als het tweede bereik korter is dan het eerste, resulteert het niet-gedefinieerde gedrag. Als het tweede bereik langer is, kunnen de resultaten nog steeds onjuist zijn omdat de vergelijking nooit voorbij het einde van het eerste bereik loopt.

Verschillende containers vergelijken (C++14)

In C++14 en hoger kunt u verschillende containers en/of verschillende elemententypen vergelijken met behulp van een van de std::equal, std::mismatchof std::is_permutation functie-overbelastingen die twee volledige bereiken in beslag nemen. Met deze overbelastingen kunt u containers vergelijken met verschillende lengtes. Deze overbelastingen zijn veel minder gevoelig voor gebruikersfouten en zijn geoptimaliseerd om onwaar te retourneren in constante tijd wanneer containers met verschillende lengten worden vergeleken. Daarom raden we u aan deze overbelastingen te gebruiken, tenzij u een duidelijke reden hebt om niet te doen, of als u een std::list container gebruikt, die niet profiteert van de optimalisaties voor twee bereiken.

Zie ook

Parallelle containers
<sample container>
Thread Safety in de standaardbibliotheek van C++