La boucle for basée sur une plage est une syntaxe pratique pour itérer sur une plage de valeurs. Cependant, il ne permet pas d'accéder à l'index de l'objet actuel dans la boucle. Cela peut être problématique si vous devez effectuer des opérations sur l'objet en fonction de sa position dans le conteneur.
Heureusement, il existe un moyen de trouver l'index de l'objet actuel sans maintenir un itérateur séparé. L’astuce consiste à utiliser une technique de composition. Au lieu de parcourir directement le conteneur, nous pouvons le « compresser » avec un index en cours de route.
Voici comment cela fonctionne :
Le code postal est une classe qui crée un nouveau type d'itérateur qui encapsule l'itérateur d'origine et ajoute un champ d'index. La structure iterator_extractor est utilisée pour extraire le type d'itérateur sous-jacent du conteneur.
template <typename T> class Indexer { public: class iterator { typedef typename iterator_extractor<T>::type inner_iterator; typedef typename std::iterator_traits<inner_iterator>::reference inner_reference; public: typedef std::pair<size_t, inner_reference> reference; iterator(inner_iterator it): _pos(0), _it(it) {} reference operator*() const { return reference(_pos, *_it); } iterator& operator++() { ++_pos; ++_it; return *this; } iterator operator++(int) { iterator tmp(*this); ++*this; return tmp; } bool operator==(iterator const& it) const { return _it == it._it; } bool operator!=(iterator const& it) const { return !(*this == it); } private: size_t _pos; inner_iterator _it; }; Indexer(T& t): _container(t) {} iterator begin() const { return iterator(_container.begin()); } iterator end() const { return iterator(_container.end()); } private: T& _container; }; // class Indexer template <typename T> Indexer<T> index(T& t) { return Indexer<T>(t); }
Pour utiliser le code zippé, enveloppez simplement le conteneur dans la fonction d'indexation et itérez sur la plage d’itérateurs résultante. L'itérateur fournira à la fois l'index et la valeur de l'objet actuel.
std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9}; for (auto p: index(v)) { std::cout << p.first << ": " << p.second << "\n"; }
Cela affichera :
0: 1 1: 2 2: 3 3: 4 4: 5 5: 6 6: 7 7: 8 8: 9
Alors que le code postal est un outil puissant pour trouver l'index de l'objet actuel dans une boucle for basée sur une plage, il existe également des approches alternatives qui peuvent être plus adaptées dans certains cas. situations.
Itérateur séparé : Le maintien d'un itérateur séparé permet un contrôle plus direct sur le processus d'itération. Vous pouvez utiliser l'itérateur pour rechercher explicitement l'index de l'objet actuel ou pour effectuer d'autres opérations sur le conteneur.
Boost.Range : La bibliothèque Boost.Range fournit un certain nombre d'outils pour plages de manipulation, y compris l'adaptateur indexé. L'adaptateur indexé peut être utilisé pour créer une plage d'itérateurs qui associe chaque élément de la plage d'origine à son index.
Classe de plage personnalisée : Vous pouvez créer votre propre classe de plage personnalisée qui fournit un itérateur qui inclut l’index de l’objet actuel. Cette approche vous offre la plus grande flexibilité dans le contrôle du processus d'itération.
Il existe plusieurs options disponibles pour trouver l'index de l'objet actuel dans une boucle for basée sur une plage. Le meilleur choix pour votre application dépendra des exigences spécifiques et des compromis impliqués.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!