Ir para o conteúdo

Última atualização:2026-10-12

Invalidação de iteradores na STL

https://stackoverflow.com/questions/6438086/iterator-invalidation-rules-for-c-containers

Inserção Contêineres sequenciais

  • vector: todos os iteradores e referências anteriores ao ponto de inserção permanecem válidos, a menos que o novo tamanho do contêiner exceda a capacidade anterior (nesse caso, todos os iteradores e referências são invalidados) [23.3.6.5/1]
  • deque: todos os iteradores e referências são invalidados, a menos que o elemento inserido esteja em uma das extremidades do deque (frente ou fundo) (nesse caso, todos os iteradores são invalidados, mas as referências aos elementos permanecem válidas) [23.3.3.4/1]
  • list: nenhum iterador ou referência é invalidado [23.3.5.4/1]
  • forward_list: nenhum iterador ou referência é invalidado (aplica-se a insert_after) [23.3.4.5/1]
  • array: (não aplicável)

Contêineres associativos

  • [multi]{set,map}: nenhum iterador ou referência é invalidado [23.2.4/9]

Contêineres associativos não ordenados

  • unordered_[multi]{set,map}: quando ocorre um rehash, todos os iteradores são invalidados, mas as referências permanecem válidas [23.2.⅝]. Se a inserção não fizer com que o tamanho do contêiner exceda z * B, não ocorre rehash, onde z é o fator de carga máximo e B é o número atual de buckets [23.2.5/14]

Adaptadores de contêiner

  • stack: herda do contêiner subjacente
  • queue: herda do contêiner subjacente
  • priority_queue: herda do contêiner subjacente

Remoção Contêineres sequenciais

  • vector: todo iterador e referência a partir do ponto de remoção são invalidados [23.3.6.5/3]
  • deque: remover o último elemento invalida apenas iteradores e referências ao elemento removido e o iterador past-the-end; remover o primeiro elemento invalida apenas iteradores e referências ao elemento removido; remover qualquer outro elemento invalida todos os iteradores e referências (incluindo o iterador past-the-end) [23.3.3.4/4]
  • list: apenas iteradores e referências ao elemento removido são invalidados [23.3.5.4/3]
  • forward_list: apenas iteradores e referências ao elemento removido são invalidados (aplica-se a erase_after) [23.3.4.5/1]
  • array: (não aplicável)

Contêineres associativos

  • [multi]{set,map}: apenas iteradores e referências ao elemento removido são invalidados [23.2.4/9]

Contêineres associativos não ordenados

  • unordered_[multi]{set,map}: apenas iteradores e referências ao elemento removido são invalidados [23.2.5/13]

Adaptadores de contêiner

  • stack: herda do contêiner subjacente
  • queue: herda do contêiner subjacente
  • priority_queue: herda do contêiner subjacente

Redimensionamento - vector: o mesmo que para inserção/remoção [23.3.6.5/12] - deque: o mesmo que para inserção/remoção [23.3.3.3/3] - list: o mesmo que para inserção/remoção [23.3.5.3/1] - forward_list: o mesmo que para inserção/remoção [23.3.4.5/25] - array: (não aplicável)

Nota 1 Salvo disposição em contrário explicitamente definida (seja explicitamente ou por meio de funções que definem outras funções), chamar uma função-membro de um contêiner ou passar um contêiner como argumento a uma função da biblioteca não deve invalidar iteradores para objetos nesse contêiner nem alterar seus valores. [23.2.1/11]

Nota 2 Nenhuma função swap() invalida referências, ponteiros ou iteradores que apontem para os elementos dos contêineres que estão sendo trocados. [Nota: o iterador end() não aponta para nenhum elemento, de modo que pode ser invalidado. — fim da nota] [23.2.1/10]

Nota 3 Com exceção da ressalva acima sobre swap(), não está claro se os iteradores "end" estão sujeitos a cada uma das regras de contêiner acima; em qualquer caso, você deve assumir que estão.

Nota 4 vector e todos os contêineres associativos não ordenados oferecem suporte a reserve(n), que garante que nenhum redimensionamento automático ocorra pelo menos até que o tamanho do contêiner cresça para n. Deve-se ter cautela com os contêineres associativos não ordenados, pois propostas futuras permitirão especificar um fator de carga mínimo, o que permitirá que um rehash ocorra na inserção depois que remoções suficientes reduzam o tamanho do contêiner abaixo desse mínimo; portanto, após remoções, essa garantia deve ser considerada possivelmente inválida.

https://en.cppreference.com/w/cpp/container#Iterator_invalidation

for (auto it = c.begin(); it != c.end(); /*inc in loop*/)
{
   if (it->shouldErase())
   {
         it = c.erase(it);
         continue;
    }
    ...
    ++it;
}
auto is_dead = [](auto const& e) { return !(e->is_alive()); };

std::erase_if(m_entities, is_dead);
std::erase_if(m_entity_map, is_dead);

erase_if ou remove_if

https://stackoverflow.com/questions/39019806/using-erase-remove-if-idiom

https://kera.name/articles/2011/06/iterator-invalidation-rules-c0x/

Tópicos relacionados

Comentários