Je suis curieux de connaître le raisonnement qui sous-tend le code suivant. Pour une carte donnée, je peux supprimer une plage allant jusqu'à, mais non incluse, end()
(évidemment) en utilisant le code suivant :
map<string, int> myMap;
myMap["one"] = 1;
myMap["two"] = 2;
myMap["three"] = 3;
map<string, int>::iterator it = myMap.find("two");
myMap.erase( it, myMap.end() );
Cette opération permet d'effacer les deux derniers éléments de la plage. Cependant, si j'utilisais la version d'erase avec un seul itérateur, je m'attendais à passer myMap.end()
n'aboutit à aucune action puisque l'itérateur se trouve clairement à la fin de la collection. Cette situation est différente de celle d'un itérateur corrompu ou invalide, qui entraînerait clairement un comportement indéfini.
Cependant, lorsque je fais cela :
myMap.erase( myMap.end() );
J'obtiens simplement une erreur de segmentation. Je n'aurais pas pensé qu'il était difficile pour map de vérifier si l'itérateur était égal à end()
et ne pas prendre de mesures dans ce cas. Y a-t-il une raison subtile à cela qui m'échappe ? J'ai remarqué que même cela fonctionne :
myMap.erase( myMap.end(), myMap.end() );
(c'est-à-dire qu'il ne fait rien)
La raison pour laquelle je pose cette question est que j'ai un code qui reçoit un itérateur valide de la collection (mais qui pourrait être end()
) et je voulais simplement passer cela dans erase plutôt que d'avoir à vérifier d'abord comme ceci :
if ( it != myMap.end() )
myMap.erase( it );
ce qui me semble un peu lourd. L'alternative est de recoder pour pouvoir utiliser la surcharge d'effacement de type by-key mais je préfère ne pas trop réécrire si je peux m'en empêcher.