Puis-je faire des calculs normaux avec des itérateurs, c'est-à-dire simplement l'incrémenter en ajoutant un nombre?
Par exemple, si je veux supprimer l'élément vec[3]
, je peux juste faire ceci:
std::vector<int> vec;
for(int i = 0; i < 5; ++i){
vec.Push_back(i);
}
vec.erase(vec.begin() + 3); // removes vec[3] element
Cela fonctionne pour moi (g ++), mais je ne sais pas si c'est garanti pour fonctionner.
Cela fonctionne si l'itérateur est un itérateur à accès aléatoire, quels sont les itérateurs du vecteur (voir référence ). La fonction STL std::advance
peut être utilisé pour faire avancer un itérateur générique, mais comme il ne renvoie pas l'itérateur, j'ai tendance à utiliser + s'il est disponible car il a l'air plus propre.
Note C++ 11
Maintenant, il y a std::next
et std::prev
, qui faire retourne l'itérateur, donc si vous travaillez dans un pays modèle, vous pouvez les utiliser pour faire avancer un itérateur générique et avoir toujours du code propre.
Un point subtil est que le operator+
prend un Distance
; c'est-à-dire un entier signé. Si vous incrémentez l'itérateur d'un signe non signé, vous risquez de perdre en précision et de vous surprendre. Par exemple sur un système 64 bits,
std::size_t n = (1 << 64) - 2;
std::vector<double> vec(1 << 64);
std::vector<double> slice(vec.begin() + n, vec.end());
conduit à un comportement défini par l'implémentation. Avec g++
ou clang
, vous pouvez demander au compilateur de vous avertir de ces conversions indésirables avec l'indicateur d'avertissement -Wsign-conversion
qui ne fait pas partie du canonique -Wall
ou -Wextra
.
Une solution consiste à travailler directement sur le pointeur
std::vector<double> slice(vec.data() + n, vec.data() + vec.size());
Ce n'est pas joli mais correct. Dans certains cas, vous devez construire l'itérateur manuellement, par exemple
std::vector<double>::iterator fromHere{vec.data() + n};
vec.erase(fromHere, vec.end());
Il fonctionne avec des itérateurs à accès aléatoire. En général, vous voudrez peut-être regarder std :: advance qui est plus générique. Assurez-vous simplement de comprendre les implications sur les performances de l'utilisation de ce modèle de fonction.