Pergunta

Estou entrando no C ++ da Java e tenho uma situação de design comum em que tenho um elemento (um não primitivo) que gostaria de remover de um vetor de std ::.

Em Java, eu escrevia algo como: ArrayList.remove (ArrayList.indexof (myclassInstance));

Em C ++, com um vetor STD ::, qual é a melhor maneira / mais performante / mais limpa de fazer isso?

A melhor coisa que consigo pensar é criar uma referência à instância que estou procurando e depois itera através do vetor até encontrar essa referência. Essencialmente, para comparar o endereço de memória de cada elemento no vetor com a referência até que eu receba uma correspondência.

Estou no caminho certo? Ou existe uma maneira melhor de fazer isso? (Talvez usando um contêiner DST diferente, eu só usei STD :: Vector até agora.)

Foi útil?

Solução

#include <algorithm>

std::vector<Foo>::iterator it = std::find(vec.begin(), vec.end(), foo_2b_found);
if (it != vec.end()) vec.erase(it);

Outras dicas

Usar std::find para encontrar o elemento e vector::erase para removê -lo.

std::find essencialmente itera através do vetor para encontrar o elemento, e você não pode fazer melhor com um vetor simples (o mesmo é o caso do Java's ArrayList). Se você deve ou não usar um contêiner diferente depende de seus requisitos.

Se você quiser pesquisar linearmente através do vetor, então

seq.erase( std::find( seq.begin(), seq.end(), elt ));

Se você tem um predicado e deseja remover todos os itens que correspondem ao predicado, então:

seq.erase( std::remove_if( seq.begin(), seq.end(), Pred ), seq.end());

Nenhum desses métodos é a maneira mais com desempenho, porque eles exigem pesquisa linear e, mesmo que seu elemento seja encontrado desde o início, a apagação é cara porque precisa mover todos os outros elementos por posição para mantê -los contíguos.

O uso da lista STD :: abordaria o último deles: a pesquisa seria linear, mas a apagamento seria tempo constante.

Se for possível armazenar seus elementos em um contêiner associativo que use uma pesquisa chave, isso seria mais eficiente: o (log n) Pesquisa e remoção de tempo constante.

Um mapa de hash pode ser ainda melhor, perto da constante pesquisa e remoção de tempo.

Para o que você está sugerindo, ou seja, apagando pelo ponteiro do objeto, você pode usar o std :: definido para o seu tipo T. Em seguida, use mySet.erase( pt ); onde PT é o seu ponteiro. Você precisa gerenciar a vida útil de seus ponteiros, é claro, mas o fato de saber qual deles apagar sua coleção sugere que você tem uma cópia em outro lugar.

Você pode usar std :: set, sharedptrless>

onde você define sharedptr sem a seguinte maneira:

template< typename T >
struct SharedPtrLess
{
   bool operator()( boost::shared_ptr<T> left, boost::shared_ptr<T> right ) const
   {
     return std::less<T>()( left.get(), right.get());
   }
};
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top