2009-11-30 4 views
2

Dans le livre « C++ In A Nutshell », il y a le code exemple suivantAidez-moi à comprendre std :: effacer

std::vector<int> data 
... 
std::erase(std::remove(data.begin(), data.end(), 42), 
    data.end()); 

Je pensais que « effacement » était une fonction membre, ne devrait donc pas être 'data.erase' plutôt que 'std :: erase'? Le compilateur C++ peut-il indiquer de quel membre vous voulez appeler une fonction membre, ou le livre at-il omis la documentation d'une fonction de gabarit d'effacement ou l'exemple est-il faux?

Répondre

13

erase est une fonction de membre. L'échantillon fourni est incorrect.

0

Edit: Désolé leur est pas générique d'effacement, juste revérifié

+0

Il n'y a pas algorithme générique 'erase'. –

+0

... même pas dans '' (allez-y, essayez-le). –

+0

oui j'ai été incorrect en disant qu'il y avait un algorithme d'effacement générique (je me suis souvenu mal). mais il existe un en-tête d'algorithme dans la bibliothèque standard. Qui comprend beaucoup d'algorithmes génériques (trouver, inclut, etc.), qui fonctionne avec les différents conteneurs stl. – lkristjansen

7

Il n'y a pas std::erase. std::map::erase, std::list::erase existe. Mais il n'existe pas de std::erase.

Regardez this question à propos de fantôme std :: erase.

+0

Pour être précis, tous les conteneurs de séquence et associatifs fournissent le membre 'erase()' (cela fait partie de leurs exigences), ainsi que 'std :: basic_string'. –

3

Oui, l'effacement est une fonction membre, il doit donc être data.erase() au lieu de std::erase().

3

Votre observation est correcte. 'Effacer' devrait être une fonction membre. Seule une fonction membre sur un conteneur peut modifier la taille de la mémoire de ce conteneur.

0

Il existe un algorithme appelé std :: remove. Et appeler effacement sur la structure de données. remove déplace tous les éléments à effacer à la fin de la plage de l'itérateur et renvoie le premier élément à supprimer. Renvoie end() si l'élément n'a pas pu être trouvé. Alors vous appelez erase on range en commençant par la valeur de retour de std :: remove et la fin de la structure de données.

Voir: http://www.sgi.com/tech/stl/remove.html

Notez que supprimer ne fonctionne pas avec datastructures commandés, les éléments ne peuvent pas être réorganisées. Remove est linéaire, et donc supprimerait un vecteur de la fin jusqu'à la fin. Comme il n'aurait pas besoin de gonfler les éléments après les éléments à enlever.

std::vector<int> data 
... 
data.erase(std::remove(data.begin(), data.end(), 42), data.end()) 

par rapport à quelque chose comme ce qui est O (N ** 2)

std::vector<int> data 
... 
for (i = data.begin(), i != data.end(); ++i) { 
    if (*i == 42) data.erase(i) ; 
} 
+0

Relisez la question. Il utilise std :: remove. Vous n'avez pas à dire "ce qui ressemble à ce qu'ils voulaient", parce que c'est ce qu'ils ont utilisé. –

Questions connexes