Templates e STL
Código genérico, escolha de contentores, iteradores, invalidação, algoritmos e comparadores.
Declarar um modelo de função
template <typename T>
T maior(T a, T b) { return a < b ? b : a; }
maior(3, 8)deduzint.maior(3, 2.5)não deduz um só tipo. Usamaior<double>(3, 2.5).- O tipo tem de oferecer as operações usadas.
- Definições ficam no cabeçalho para a instanciação as ver.
Pilha<int> e Pilha<string> são tipos distintos. Retirar do topo exige confirmar não vazio.
Que contentor escolho?
| Preciso de | Escolhe |
|---|---|
| Índice constante, tamanho fixo | array<T, N> |
| Índice constante, crescer no fim | vector<T> |
| Inserir nos dois extremos | deque<T> |
| Inserir com posição conhecida | list<T> constante; localizar o elemento custa O(n) |
| Chave ordenada única | set, map; procura, inserção e remoção em O(log n) comparações |
| Chave sem ordem, média constante | unordered_map; média O(1) com boa distribuição das chaves e hash/igualdade de custo constante; pior caso linear |
size()conta os elementos existentes.capacity()conta a capacidade em elementos.reserve(n)só aumenta a reserva quandonexcede a capacidade atual, sem criar elementos, e nunca a diminui.v[i]não verifica.at(i)verifica.front,back,pop_backexigem não vazio.m[chave]insere um valor construído por omissão quando a chave falta:intfica0,stringfica vazia.findconsulta sem inserir.
Iteradores sem sustos
[begin(), end())inclui o início e exclui o fim. Nunca leiasend().vectortem acesso aleatório.listavança e recua.sortexige aleatório.- Realocar
vectorinvalida todos os acessos aos elementos. - No
vector,eraseinvalida os acessos da posição removida em diante. Continua com o iterador devolvido. Nalist, só o elemento removido perde validade.
for (auto it = v.begin(); it != v.end(); ) {
if (*it < 0) it = v.erase(it);
else ++it;
}
unique não apaga sozinho
unique junta iguais adjacentes e devolve o fim do prefixo útil. O tamanho continua igual.
std::sort(v.begin(), v.end());
v.erase(std::unique(v.begin(), v.end()), v.end());
- A cauda continua desreferenciável, com estado válido mas não especificado. O resultado lógico termina no iterador devolvido. Usa
erasee não contes com esses valores. - Só junta adjacentes. Para todos os repetidos, ordena antes.
lower_bounddevolve a primeira posição que não vem antes do alvo, mas exige intervalo particionado pelo mesmo comparador, normalmente ordenado. Confirmait != end()e a igualdade antes de concluir que o valor existe.- Comparador estrito exige
comp(x, x) == false.<=não serve. Só esse teste não prova transitividade.
Agregação: resume cada chave num vetor e ordena os resumos. Média das médias pesa igual cada grupo. map<double, string> perde empatados.