Conceitos básicos da biblioteca C ++ padrão

Este artigo define os conceitos básicos da biblioteca C ++ padrão. É dado para se referir a ele no futuro.

A maior parte da Biblioteca Padrão C ++ é a STL (Biblioteca de Modelos Padrão). A biblioteca STL contém cinco tipos principais de componentes:

  • container : controla um conjunto de objetos na memória.
  • iterador : fornece um algoritmo para o algoritmo acessar o conteúdo do contêiner.
  • algoritmo : define um procedimento computacional.
  • objeto de função : encapsula uma função em um objeto para uso por outros componentes.
  • adaptador : adapta um componente para fornecer uma interface diferente.



Todos os componentes atendem a vários requisitos, portanto, estão em bom acordo.

A partir da definição do contêiner, segue-se que qualquer estrutura de dados do usuário é um contêiner. No nosso caso, os contêineres possuem estruturas de dados padrão , como uma lista, vetor, dicionário e muitas outras. Os requisitos formais para contêineres são bastante extensos, mas a regra básica é o acesso a elementos. O acesso aos elementos do contêiner é realizado através de objetos especiais - iteradores (veja abaixo). Você pode não saber como os elementos do contêiner estão localizados na memória, mas sabe com certeza que os iteradores podem ser iterados um por um e cada um deles fornecerá acesso ao elemento. Um iterador apontando para o primeiro elemento pode ser obtido usando o método iterador begin (); recipiente. Um iterador apontando para o último elemento pode ser obtido usando o método iterator end (); recipiente. Em outras palavras, os iteradores estão localizados em meio intervalo (ou meio segmento), que pode ser formalmente escrito como [begin, end). Exemplo de declaração de contêiner:

struct a_container { struct an_iterator; an_iterator begin(); an_iterator end(); }; 

O padrão C ++ 20 esperado sugere o uso de uma estrutura que encapsula meias- faixas - faixas


Um iterador é um objeto que fornece acesso aos elementos do contêiner e permite que eles sejam classificados. Um iterador é uma propriedade do contêiner. Nas primeiras implementações da biblioteca padrão C ++, um iterador foi implementado como um ponteiro para um elemento de contêiner. Nas implementações modernas, essa é uma classe que encapsula um ponteiro para um objeto de contêiner.

Os principais requisitos para os iteradores são a presença de operadores de desreferenciamento e incremento. Abaixo está uma declaração de contêiner com um iterador.

 template<typename TYPE> struct a_container { struct an_iterator { void operator++(); TYPE& operator*(); }; an_iterator begin(); an_iterator end(); }; 

Não posso dar uma definição melhor do algoritmo que a padrão: um algoritmo é uma sequência de ações que levam ao resultado desejado em um número finito de etapas .

No caso do STL, os algoritmos são implementados por funções de gabarito que tomam intervalos de iteradores como parâmetros de entrada. A assinatura geral desses algoritmos é descrita da seguinte maneira:

 template<typename ITERATOR, typename RESULT> RESULT an_algorithm(ITERATOR first, ITERATOR last, ...); 

Em uma declaração de classe, você pode substituir o operador (). Se esse operador for substituído em uma classe, os objetos dessa classe receberão propriedades das funções (eles podem ser usados ​​como funções). Tais objetos são chamados funcionais ou functores . É conveniente usar functores quando uma função deve ter "memória", além de substituir ponteiros para funções.
Começando com o padrão C ++ 11, existe a possibilidade de uma breve notação de functors - funções lambda.
Não há requisitos especiais para functores. A menos que, às vezes, a herança da função functor seja necessária (até o padrão C ++ 11 - função unária ou função binária). Um pequeno exemplo de uma implementação de functor:

 template<typename TYPE> struct plus{ TYPE operator ()(const TYPE& p1, const TYPE& p2) const{ return p1 + p2; } }; 

A STL também oferece várias classes e funções (funções) que transformam a interface na correta. Em particular, há um adaptador de pilha que implementa uma pilha baseada em contêineres. Como exemplo, podemos considerar o adaptador de uma função binária para uma unária (no momento em que essa função está obsoleta no padrão C ++):

 template<typename BIDIRECTIONAL_FUNCTION, typename TYPE> class bind1st { BIDIRECTIONAL_FUNCTION _bf; TYPE _first; public: bind1st(BIDIRECTIONAL_FUNCTION bf, TYPE first): _bf(bf), _first(first) {} TYPE operator()(const TYPE& p) const { return _bf(_first, p); } }; 

Para leitura independente


  1. Rascunho do C ++ 20 no github
  2. Referência C ++
  3. Desenvolvimento de aplicativos em C ++
  4. Range-v3, proposta de padrão

Source: https://habr.com/ru/post/pt434986/


All Articles