c++ - Can I get the index of an item from within a range based for loop? -


i have defined deque of pointers this:

std::deque<boardsquare *> mydeque; 

i use range based loops deque:

for (boardsquare * b : mydeque) {      // involving index of b } 

is possible index of item within range based loop?

i came solution — or rather experimental solution. here how end using it:

for(auto item : make_indexable(v)) {       //std::get<0>(item) index       //std::get<1>(item) object } 

and here goes minimal implementation (it demonstrate basic idea):

#include <tuple> #include <functional>  template<typename c> struct indexed_container {     struct indexed_iterator     {         typedef typename c::value_type value_type;         typedef std::tuple<size_t, std::reference_wrapper<value_type>> tuple_type;          typename c::iterator _it;         size_t _index;          indexed_iterator(typename c::iterator it) : _it(it), _index(0) {}          indexed_iterator& operator++()         {             ++_it;             ++_index;             return *this;         }         bool operator == (indexed_iterator const & other)         {             return _it == other._it;         }         bool operator != (indexed_iterator const & other)         {             return _it != other._it;         }         tuple_type operator*()         {             return std::make_tuple(_index, std::ref(*_it));         }     };      indexed_container(c & c) : _c(c) {}      indexed_iterator begin()     {         return indexed_iterator(_c.begin());     }     indexed_iterator end()     {         return indexed_iterator(_c.end());     } private:     c & _c; };  template<typename c> auto make_indexable(c & c) -> indexed_container<c> {     return indexed_container<c>(c);  } 

test code:

#include <iostream> #include <vector>  int main() {     std::vector<int> v{1,2,3};     for(auto item : make_indexable(v))     {         std::cout << std::get<0>(item) << " => " << std::get<1>(item) << std::endl;          std::get<1>(item) *= 10; //modify value!     }     std::cout << "\nmodified\n";     for(auto item : make_indexable(v))     {         std::cout << std::get<0>(item) << " => " << std::get<1>(item) << std::endl;     } } 

output:

0 => 1 1 => 2 2 => 3  modified 0 => 10 1 => 20 2 => 30 

online demo

note solution not perfect, not work temporaries , const containers (and containers of const objects). also, right underlying object returned reference if write auto item opposed auto & item (in fact, cannot write auto &item). think these issues can fixed bit more effort , careful design. after all, demonstration of basic idea.


Comments