Unfortunately, you can’t put the increment into the range based for loop. However, in your specific case – as std::vector
stores its elements contigously in memory – you can simulate option 2 by falling back to pointers (thanks to @M.M and @Jarod42 for corrections and improvements):
for ( const int& val : v ) {
std::cout << "v at index " << &val-v.data() << " is " << val;
}
more generic:
for ( const auto& val : v ) {
std::cout << "v at index " << std::addressof(val)-v.data() << " is " << val;
}
The other thing you can do is to write a index_range
class, that represents a collections of indexes over which you can iterate in your range based for loop:
struct index_range_it {
size_t idx;
size_t operator*(){
return idx;
}
index_range_it& operator++() {
idx++;
return (*this);
}
};
bool operator!=(index_range_it l,index_range_it r) {
return l.idx != r.idx;
}
struct index_range {
size_t size;
index_range_it end(){return index_range_it{size};}
index_range_it begin(){return index_range_it{0};}
};
int main()
{
for (auto i: index_range{v.size()}){
std::cout << "v at index " << i << " is " << v[i];
}
}
A full fledged implementation of this idea can be found e.g. here
Such a range can then also be composed to something, where the iterator returns a proxy object containing the index as well as a reference to the current object and with c++17’s structured binding that would be even more convenient to use.