Effacer des éléments spécifiques dans std :: map
Je veux effacer certains éléments de ma std::map.
J'ai écrit effacer + remove_if technique à laquelle j'ai toujours le faire avec d'autres conteneurs de séquence.
Mais il n'était pas à compiler avec la carte. Pourquoi?
Et Comment puis-je faire ce travail?
std::map<int, int> m;
bool foo(const std::pair<int, int>& p)
{
return p.second > 15;
}
int _tmain(int argc, _TCHAR* argv[])
{
m.insert(make_pair(0, 0));
m.insert(make_pair(1, 10));
m.insert(make_pair(2, 20));
m.insert(make_pair(3, 30));
m.erase(
remove_if(m.begin(), m.end(), foo),
m.end()); //compile error
return 0;
}
source d'informationauteur Benjamin
Vous devez vous connecter pour publier un commentaire.
Écrire ce genre de carte, puisque
remove_if
de ne pas travailler pourmap
itérateurs (il met simplement la délinquance des éléments à la fin, etmap
les itérateurs ne permettent pas cela):ou si vous aimez les one-liners:
Parce que
std::map
n'est pas de séquences "conteneur" 🙂remove_if
vais essayer de mettre les éléments inutiles à la fin de la carte, mais ce sera la cause de la violation de l'implicite de la structure des données (rouge-noir arbre dans la plupart des cas) de la carte. L'implicite de la structure des données définit la place de chaque élément de la carte, et c'est pourquoiremove_if
n'est pas autorisé pourstd::map
.Vous devriez effacer des éléments de
std::map
l'un après l'autre (ou de donner un certain intervalle de temps) dans la boucle.Quelque chose comme ceci:
"Avec d'autres conteneurs de séquence" est votre erreur
map
est un associatif conteneur! Dans les conteneurs associatifs, les éléments sont définis par leur clé (par opposition à l'ordre d'insertion dans la séquence de conteneurs), et de l'effacement des éléments par clé:Effacement d'une valeur de clé a la même complexité que de recherche (par exemple, O(log n) pour les cartes, O(1) pour les non-ordonnée de la carte, etc.). Alternativement, vous pouvez l'effacer par itérateur en temps constant. L'effacement d'un itérateur invalide que itérateur, mais pas d'autres (encore une fois contrairement à conteneurs de séquence), donc si vous voulez effectuer une itération sur une carte, typique de l'idiome est-ce:
Cet idiome ne fonctionne que pour la séquence comme des conteneurs - les entrées dans une carte (associatif) ne peut pas être re-commandé (la clé ne change pas, alors, comment vous pouvez vous attendre à déplacer une entrée à une autre position - par exemple à la fin). La bonne façon de le faire est de trouver l'entrée et la supprimer - c'est à dire
it = map.find(); map.erase(it++)
Essayer quelque chose comme cela
Lors de l'utilisation de
remove_if
le type de déréférencé les itérateurs doivent satisfaire aux exigences de CopyAssignable. Qu'en est-il devrait être possible d'affecter une valeur à une autre.Pour
std::map<int, int>
la valeur eststd::pair<const int, int>
qui représente les paires clé-valeur de la carte et qui n'est pas CopyAssignable. La raison de cetteconst int
pour clé est de savoir comment la carte fonctionne en interne, comme d'autres personnes ont déjà fait.Par la façon dont vous obtiendrez les mêmes erreurs de compilation pour un conteneur de séquence comme ceci: