Comment incrémenter un iterator de 2?

Quelqu’un peut-il me dire comment incrémenter l’iterator de 2?

iter++ est disponible – dois-je le faire iter+2 ? Comment puis-je atteindre cet objective?

std::advance( iter, 2 );

Cette méthode fonctionnera pour les iterators qui ne sont pas des iterators à access aléatoire, mais elle peut toujours être spécialisée par l’implémentation pour être moins efficace que iter += 2 lorsqu’elle est utilisée avec des iterators à access aléatoire.

http://www.cplusplus.com/reference/std/iterator/advance/

 std::advance(it,n); 

où n est 2 dans votre cas.

La beauté de cette fonction est que si “it” est un iterator à access aléatoire, le

 it += n 

l’opération est utilisée (c.-à-d. vecteur <,,> :: iterator). Sinon c’est rendu à

 for(int i = 0; i < n; i++) ++it; 

(ie liste <..> :: iterator)

Si vous n’avez pas de lvalue modifiable d’un iterator, ou si vous souhaitez obtenir une copie d’un iterator donné (en laissant l’original intact), alors C ++ 11 intègre de nouvelles fonctions d’aide – std::next / std::prev :

 std::next(iter, 2); // returns a copy of iter incremented by 2 std::next(std::begin(v), 2); // returns a copy of begin(v) incremented by 2 std::prev(iter, 2); // returns a copy of iter decremented by 2 

Vous pouvez utiliser l’opérateur ‘assignation par addition’

 iter += 2; 

Si vous ne savez pas si vous avez ou non les éléments suivants dans votre conteneur, vous devez vérifier la fin de votre conteneur entre chaque incrément. Ni ++ ni std :: advance ne le feront pour vous.

 if( ++iter == collection.end()) ... // stop if( ++iter == collection.end()) ... // stop 

Vous pouvez même lancer votre propre fonction d’avance sécurisée.

Si vous êtes sûr de ne pas dépasser la fin, std :: advance (iter, 2) est la meilleure solution.

Nous pouvons utiliser à la fois l’avance et la prochaine. Mais il y a une différence entre les deux. “advance” modifie son argument et ne retourne rien. Ainsi, il peut être utilisé comme:

 vector v; v.push_back(1); v.push_back(2); auto itr = v.begin(); advance(itr, 1); //modifies the itr cout << *itr< 

"next" renvoie une copie modifiée de l'iterator

 vector v; v.push_back(1); v.push_back(2); cout << *next(v.begin(), 1) << endl; //prints 2 

En supposant que la taille de la liste ne soit pas un multiple, vous devez vous prémunir contre le débordement:

 static constexpr auto step = 2; // Guard against invalid initial iterator. if (!list.empty()) { for (auto it = list.begin(); /*nothing here*/; std::advance(it, step)) { // do stuff... // Guard against advance past end of iterator. if (std::distance(it, list.end()) > step) break; } } 

Selon l’implémentation de la collection, le calcul de la distance peut être très lent. Ci-dessous est optimale et plus lisible. La fermeture peut être transformée en un modèle d’utilitaire avec la valeur de fin de liste transmise par la référence const:

 const auto advance = [&](list_type::iterator& it, size_t step) { for (size_t i = 0; it != list.end() && i < step; std::next(it), ++i); }; static constexpr auto step = 2; for (auto it = list.begin(); it != list.end(); advance(it, step)) { // do stuff... } 

S'il n'y a pas de boucle:

 static constexpr auto step = 2; auto it = list.begin(); if (step <= list.size()) { std::advance(it, step); } 

La réponse très simple:

 ++++iter 

La longue réponse:

Vous devriez vraiment vous habituer à écrire ++iter au lieu d’ iter++ . Ce dernier doit retourner (une copie de) l’ancienne valeur, qui est différente de la nouvelle valeur; cela prend du temps et de l’espace.

Notez que l’incrément de préfixe ( ++iter ) prend une valeur et renvoie une lvalue, tandis que l’incrément postfix ( iter++ ) prend une valeur et retourne une valeur.