2010-09-23 17 views
1

Possible en double:
remove_if equivalent for std::mapGCC arbre conteneurs de données STL

Hier je l'ai écrit un programme qui utilise multiset pour stocker des éléments comme celui-ci:

std::multiset < boost::shared_ptr <CEntity> > m_Entities; 

Puis i essayer d'utiliser l'algorithme standard remove_if comme ceci:

std::remove_if(m_Entities.begin, m_Entities.end(), MarkedForDestroy); 

MAIS compilation a échoué, parce que si nous voyons dans GCC 4.4 implementaion de jeu et multiset on voit que:

typedef typename _Rep_type::const_iterator   iterator; 
typedef typename _Rep_type::const_iterator   const_iterator; 

J'ai été choqué. Je google ce moment et mieux que j'ai trouvé que cela ne contredit pas la norme. La même chose pour l'ensemble.

Comment cela ne peut pas contredire si les algorithmes standard ne fonctionnent pas? Comment je peux mieux changer de conteneur?

+1

Dupliquer de [remove_if équivalent pour std :: map] (http://stackoverflow.com/questions/800955/remove-if-equivalent-for-stdmap) –

Répondre

5

Vous ne pouvez pas utiliser l'algorithme std::remove_if sur un conteneur associatif. Vous devez écrire une boucle for et utiliser la méthode erase pour supprimer les éléments. Voir cette question similaire remove_if equivalent for std::map pour plus de détails.

+0

Merci, c'est mieux que la réponse précédente. –

-3

Parce multiset (et activé) sont immuables conteneurs, à savoir des éléments dans le conteneur ne peut pas être changé modifié en place, ils peuvent être supprimés, modifiés, et (ré) insérés.

Voir, par exemple:

  • un autre set lié réponse
  • section 27.3.2.1 dans ce tutorial

Dans des conteneurs associatifs simples, où les éléments sont les clés , les éléments sont complètement immuables; l' itérateur de type imbriqué et const_iterator sont par conséquent les mêmes.

+0

Je l'ai compris. Pourquoi c'est ainsi? Définir un ordre, pourquoi de tels problèmes? –

+1

Non, ils ne sont pas (http://www.cplusplus.com/reference/stl/multiset/insert/). –

+0

@den bardadym: Notez que 'remove_if' ne supprime pas les éléments du conteneur à la place, il déplace simplement les éléments vers la fin du conteneur. Pour les conteneurs séquentiels se déplacer vers la fin est logique, mais pour les conteneurs associatifs dans lesquels les éléments sont stockés dans un ordre trié, cela n'a pas de sens car il va rompre leur commande. – Naveen

1

Tous les conteneurs ordonnés/associatifs standard (carte, ensemble, multimap, multiset) ont des clés immuables (seulement les clés et non le conteneur entier). Quant à savoir pourquoi il suffit de regarder ce qui devrait se produire chaque fois que vous changez la valeur de la clé: le type de clé devrait en quelque sorte notifier son conteneur qu'il a changé (ce qui introduirait un couplage très serré et inutile entre le conteneur & c'est le type de clé - pour ne pas mentionner être impossible à faire pour les types fondamentaux) parce que le conteneur devrait être utilisé pour garder sa propriété de commande (ce qui est une grosse surcharge).