2017-05-27 1 views
-1

Je suis confus au sujet de la fonction de std::erase en C++.std :: effacer en C++

Le code suivant obtient la même sortie avant et après l'appel de std::erase.Mais si vous parcourez la liste après avoir effectué std::erase, la valeur effacée n'apparaît pas en sortie. Aidez-moi à comprendre std::erase.

#include<bits/stdc++.h> 
using namespace std; 

int main() 
{ 
    list<int> v; 
    v.push_back(12); 
    v.push_back(10); 
    v.push_back(20); 

    list<int>::iterator it; 
    it = v.begin(); 
    printf("%u %d\n", it, *it); 
    v.erase(it); 
    printf("%u %d\n", it, *it); 

    for(it= v.begin(); it!= v.end(); it++) 
     cout<< *it<<" "; 
    return 0; 
} 

Sortie:

"Memory address" 12 
"Memory Address" 12 
10 20 
+3

Ce qui est en fait pas clairement les [documents] (http://en.cppreference.com/w/cpp/container/list/erase)? En outre, votre sortie ne rend pas comme vous le décrivez. –

+4

En outre, [ne pas inclure ''] (http://stackoverflow.com/questions/31816095/pourquoi- ne devrait pas inclure -bits-stdc-h). –

+2

Il n'y a pas de 'std :: erase' dans la bibliothèque standard. – juanchopanza

Répondre

9

erase Invalide la iterator vous lui donnez (plus potentiellement d'autres, en fonction du conteneur).
L'utilisation et la déréférence de cet itérateur après est un comportement indéfini.

2

Selon le C++ standard par rapport à la liste des modèles de classe

Effets: Invalide seulement les itérateurs et les références aux éléments effacés.

Ainsi, le programme a un comportement indéfini.

Après cette déclaration

v.erase(it); 

l'itérateur it qui n'était initialement définie comme

it = v.begin(); 

maintenant correspondent pas à v.begin() et la sortie de la boucle

for(it= v.begin(); it!= v.end(); it++) 
    ^^^^^^^^^^^^^   
    cout<< *it<<" "; 

confirme que .

Au lieu de

v.erase(it); 

vous pouvez écrire

it = v.erase(it); 

et dans ce cas l'itérateur retourné sera en effet correspondre à l'itérateur retourné par v.begin()