Finding Element Positions in Range-Based For Loops
In programming, it is often necessary to determine the index or position of elements being iterated over. When using range-based for loops, which offer a convenient way to iterate through containers, the question arises if it is possible to retrieve the current element's index without using a separate iterator.
Solutions
1. Zipper Technique
One method involves using a technique called zippering. This involves combining the container with an index along the way, creating a new range of pairs where each pair consists of the index and the corresponding element.
struct Indexer { class iterator { iterator(typename T::iterator it): _pos(0), _it(it) {} std::pair<size_t, typename T::reference> operator*() const { return std::make_pair(_pos, *_it); } // ... }; iterator begin() const { return iterator(_container.begin()); } iterator end() const { return iterator(_container.end()); } private: T& _container; };
By using the Indexer class, it becomes possible to iterate over containers and obtain both the index and the element simultaneously.
2. Boost.Range
Another option involves utilizing the Boost.Range library. Specifically, the boost::adaptors::indexed adaptor can be employed to create a derived range that includes both the index and the element for each iteration.
std::vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9}; for (auto const& [idx, elem]: boost::adaptors::indexed(v)) { std::cout << idx << ": " << elem << "\n"; }
By iterating over the resulting range obtained from boost::adaptors::indexed, the index and the element can be accessed within the for loop.
3. Custom Iterator
In certain scenarios, it may be desirable to create a custom iterator that maintains the current index. This iterator can be used in conjunction with range-based for loops to access both the index and the element.
class IndexedIterator { private: container_type* _container; size_t _index; public: IndexedIterator(container_type* c) : _container(c), _index(0) {} bool operator!=(const IndexedIterator& other) const { return _container != other._container || _index != other._index; } std::pair<size_t, value_type> operator*() const { return std::make_pair(_index, *_container[_index]); } IndexedIterator& operator++() { _index++; return *this; } };
By defining a custom iterator and adapting it to the container's iterator type, it is possible to obtain the element and its index directly within the for loop.
The above is the detailed content of How Can I Get Element Indices in C Range-Based For Loops?. For more information, please follow other related articles on the PHP Chinese website!