Partilhar via


Contêineres de biblioteca padrão C++

A Biblioteca Padrão fornece vários contêineres seguros para tipos para armazenar coleções de objetos relacionados. Os contêineres são modelos de classe. Ao declarar uma variável de contêiner, você especifica o tipo dos elementos que o contêiner conterá. Os contêineres podem ser construídos com listas de inicializadores. Eles têm funções de membro para adicionar e remover elementos e fazer outras operações.

Você itera sobre os elementos em um contêiner e acessa os elementos individuais usando iteradores. Você pode usar iteradores explicitamente usando suas funções de membro e operadores e funções globais. Você também pode usá-los implicitamente, por exemplo, usando um loop range-for. Os iteradores para todos os contêineres da Biblioteca Padrão C++ têm uma interface comum, mas cada contêiner define seus próprios iteradores especializados.

Os contêineres podem ser divididos em três categorias: contêineres de sequência, contêineres associativos e adaptadores de contêiner.

Contêineres de seqüência

Os contêineres de sequência mantêm a ordem dos elementos inseridos que você especificar.

Um vector contêiner se comporta como uma matriz, mas pode crescer automaticamente conforme necessário. É de acesso aleatório e armazenado contíguo, e o comprimento é altamente flexível. Por essas e outras razões, vector é o contêiner de sequência preferido para a maioria dos aplicativos. Em caso de dúvida sobre que tipo de recipiente de sequência usar, comece usando um vetor! Para obter mais informações, consulte vector Class.

Um array recipiente tem alguns dos pontos fortes do vector, mas o comprimento não é tão flexível. Para obter mais informações, consulte array Class.

Um deque contêiner (fila dupla) permite inserções e exclusões rápidas no início e no final do contêiner. Ele compartilha as vantagens de acesso aleatório e comprimento flexível do vector, mas não é contíguo. Para obter mais informações, consulte deque Class.

Um list contêiner é uma lista duplamente vinculada que permite acesso bidirecional, inserções rápidas e exclusões rápidas em qualquer lugar do contêiner, mas você não pode acessar aleatoriamente um elemento no contêiner. Para obter mais informações, consulte list Class.

Um forward_list contêiner é uma lista vinculada individualmente — a versão de acesso direto do list. Para obter mais informações, consulte forward_list Class.

Contentores Associativos

Em contêineres associativos, os elementos são inseridos em uma ordem predefinida — por exemplo, como classificados em ordem ascendente. Estão também disponíveis contentores associativos não encomendados. Os contêineres associativos podem ser agrupados em dois subconjuntos: mapas e conjuntos.

Um map, às vezes referido como um dicionário, consiste em um par chave/valor. A chave é usada para ordenar a sequência e o valor é associado a essa chave. Por exemplo, um map pode conter chaves que representam cada palavra exclusiva em um texto e valores correspondentes que representam o número de vezes que cada palavra aparece no texto. A versão não ordenada do map é unordered_map. Para obter mais informações, consulte map Classe e unordered_map classe.

A set é apenas um recipiente ascendente de elementos únicos — o valor também é a chave. A versão não ordenada do set é unordered_set. Para obter mais informações, consulte set Classe e unordered_set classe.

Ambos map e set permitir que apenas uma instância de uma chave ou elemento seja inserida no contêiner. Se forem necessárias várias instâncias de elementos, use multimap ou multiset. As versões não ordenadas são unordered_multimap e unordered_multiset. Para obter mais informações, consulte multimap Classe, unordered_multimap Classe, multiset Classe e unordered_multiset Classe.

Mapas e conjuntos ordenados suportam iteradores bidirecionais, e suas contrapartes não ordenadas suportam iteradores avançados. Para obter mais informações, consulte Iteradores.

Pesquisa heterogênea em contêineres associativos (C++14)

Os contêineres associativos ordenados (map, multimap, set e multiset) agora suportam pesquisa heterogênea, o que significa que você não precisa mais passar exatamente o mesmo tipo de objeto que a chave ou elemento em funções de membro, como find() e lower_bound(). Em vez disso, você pode passar qualquer tipo para o qual um sobrecarregado operator< é definido que permite a comparação com o tipo de chave.

A pesquisa heterogênea é habilitada em uma base de aceitação quando você especifica o std::less<> comparador ou std::greater<> "functor diamante" ao declarar a variável de contêiner, conforme mostrado aqui:

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

Se você usar o comparador padrão, o contêiner se comportará exatamente como no C++11 e anteriores.

O exemplo a seguir mostra como sobrecarregar operator< para permitir que os usuários de um std::set façam pesquisas simplesmente passando uma pequena cadeia de caracteres que pode ser comparada ao membro de BigObject::id cada objeto.

#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

As seguintes funções de membro em map, multimap, set e multiset foram sobrecarregadas para suportar pesquisas heterogêneas:

  1. Encontrar

  2. contar / contagem

  3. lower_bound

  4. upper_bound

  5. equal_range

Adaptadores de contêiner

Um adaptador de contêiner é uma variação de uma sequência ou contêiner associativo que restringe a interface para simplicidade e clareza. Os adaptadores de contêiner não suportam iteradores.

Um queue contêiner segue a semântica FIFO (primeiro a entrar, primeiro a sair). O primeiro elemento enviado, ou seja, inserido na fila, é o primeiro a ser estourado, ou seja, removido da fila. Para obter mais informações, consulte queue Class.

Um priority_queue contêiner é organizado de tal forma que o elemento que tem o valor mais alto é sempre o primeiro na fila. Para obter mais informações, consulte priority_queue Class.

Um stack contêiner segue a semântica LIFO (last in, first out). O último elemento empurrado na pilha é o primeiro elemento estourado. Para obter mais informações, consulte stack Class.

Como os adaptadores de contêiner não suportam iteradores, eles não podem ser usados com os algoritmos da Biblioteca Padrão C++. Para obter mais informações, consulte Algoritmos.

Requisitos para elementos de contêiner

Em geral, os elementos inseridos em um contêiner C++ Standard Library podem ser de praticamente qualquer tipo de objeto se forem copiáveis. Elementos somente móveis—por exemplo, aqueles que vector<unique_ptr<T>> são criados usando unique_ptr<> funcionarão desde que você não chame funções de membro que tentem copiá-los.

O destruidor não tem permissão para lançar uma exceção.

Os contêineres associativos ordenados, descritos anteriormente neste artigo, devem ter um operador de comparação público definido. Por padrão, o operador é operator<, mas até mesmo os tipos que não funcionam com operator< são suportados.

Algumas operações em contêineres também podem exigir um construtor padrão público e um operador de equivalência público. Por exemplo, os contêineres associativos não ordenados exigem suporte para igualdade e hashing.

Acessando elementos de contêiner

Os elementos dos contêineres são acessados usando iteradores. Para obter mais informações, consulte Iteradores.

Observação

Você também pode usar loops baseados em intervalo para iterar em coleções C++ Standard Library.

Comparando contêineres

Todos os contêineres sobrecarregam o operador== para comparar dois contêineres do mesmo tipo que têm o mesmo tipo de elemento. Você pode usar == para comparar uma cadeia de caracteres de vetor<com outra cadeia de caracteres> de vetor<, mas não pode usá-la para comparar uma cadeia> de caracteres de vetor<com uma cadeia> de caracteres de lista<ou uma cadeia de caracteres> de vetor<com um char de vetor>*<.> Em C++98/03, você pode usar std::equal ou std::mismatch comparar tipos de contêiner e/ou tipos de elemento diferentes. Em C++11, você também pode usar std::is_permutationo . Mas em todos estes casos as funções assumem que os contentores têm o mesmo comprimento. Se o segundo intervalo for menor do que o primeiro, o comportamento indefinido resulta. Se o segundo intervalo for mais longo, os resultados ainda podem estar incorretos porque a comparação nunca continua após o final do primeiro intervalo.

Comparando contêineres diferentes (C++14)

Em C++14 e posterior, você pode comparar contêineres diferentes e/ou tipos de elementos diferentes usando uma das std::equalstd::mismatchsobrecargas , ou std::is_permutation função que levam dois intervalos completos. Estas sobrecargas permitem-lhe comparar contentores com comprimentos diferentes. Essas sobrecargas são muito menos suscetíveis a erros do usuário e são otimizadas para retornar false em tempo constante quando contêineres de comprimentos diferentes são comparados. Portanto, recomendamos que você use essas sobrecargas, a menos que tenha um motivo claro para não fazê-lo ou esteja usando um std::list contêiner, que não se beneficia das otimizações de intervalo duplo.

Ver também

Contentores paralelos
<sample container>
segurança de threads na biblioteca padrão C++