How to Determine an Object's Index in a Range-Based for Loop
In the context of range-based for loops, it is often desirable to access the index of the current element within the container. Consider the following code:
vector<int> list; for (auto& elem : list) { int i = elem; }
In this scenario, you may want to know the position of elem in the list vector without maintaining a separate iterator.
Zipper-Based Approach
To achieve this, a "zipper" approach can be employed. Instead of iterating directly over the container, you can "zip" it with an index along the way.
template <typename T> struct iterator_extractor { typedef typename T::iterator type; }; template <typename T> struct iterator_extractor<T const&> { typedef typename T::const_iterator type; }; template <typename T> class Indexer { public: class iterator { public: typedef std::pair<size_t, typename iterator_extractor<T>::type::reference> reference; iterator(typename iterator_extractor<T>::type 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==(const iterator& it) const { return _it == it._it; } bool operator!=(const iterator& it) const { return !(*this == it); } private: size_t _pos; typename iterator_extractor<T>::type _it; }; Indexer(T& t) : _container(t) {} iterator begin() const { return iterator(_container.begin()); } iterator end() const { return iterator(_container.end()); } private: T& _container; }; template <typename T> Indexer<T>& index(T& t) { return Indexer<T>(t); }
This code creates an Indexer class that provides an iterator which combines the element and its index in a pair. By utilizing this Indexer, you can access the index and element simultaneously.
Example Usage
The following code demonstrates how to use the zipper approach:
#include <iostream> #include <vector> using namespace std; int main() { vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9}; for (auto p : index(v)) { cout << p.first << ": " << p.second << "\n"; } return 0; }
This code will print the index and element values in the following format:
0: 1 1: 2 2: 3 3: 4 4: 5 5: 6 6: 7 7: 8 8: 9
The above is the detailed content of How to Get the Index of an Element in a C Range-Based For Loop?. For more information, please follow other related articles on the PHP Chinese website!