Reputation: 361
I've got a question. I have a vector that contains tuples:
vector<tuple<int, int> > my_vector
Let's say I want to turn my for loop iterator in an index for whatever reason:
// Example program
#include <vector>
#include <tuple>
using namespace std;
int main()
{
vector<tuple<int, int> > my_vector;
my_vector.push_back(make_tuple(1, 1));
my_vector.push_back(make_tuple(2, 2));
my_vector.push_back(make_tuple(3, 3));
for (auto iterator : my_vector)
{
size_t index = distance(my_vector.begin(), iterator);
}
}
I honestly do not understand what I have to change to get it running. The problems seems to be my use of the iterator in distance
. Maybe somebody can give me some advice.
Upvotes: 3
Views: 10975
Reputation: 310920
In the range based loop it is value of a container is assigned not an iterator.
So either use the following for loop
#include <iterator>
//...
for (auto it = std::begin(my_vector); it != std::end(my_vector); ++it)
{
size_t index = std::distance(std::begin(my_vector), it);
}
Or use an ordinary for loop with an index.
for (std::vector<std::tuple<int, int>>::size_type i = 0; i != my_vector.size(); i++)
{
auto it = std::next(std::begin(myvector), i);
}
Upvotes: 0
Reputation: 238301
C++ turn vector iterator into index
You can do it like this:
std::size_t index = std::distance(std::begin(my_vector), iterator);
But before you can get an index from an iterator, you first need to have an iterator. Example of an iterator to a vector:
// iterator to i'th element
auto iterator = std::next(my_vector.begin(), i);
for (auto iterator : my_vector)
Just naming a variable iterator does not make it an iterator. A range based loop goes over the elements of the container. The elements of this vector are tuples, not iterators.
The canonical way to have an index when iterating elements of a vector is to use a traditional index loop:
using my_vec_t = decltype(my_vector);
for (my_vec_t::size_type i = 0; i < my_vector.size(); i++)
If you really want to have the index in a range-for loop, that's possible using pointers:
auto* front = &my_vector.front();
for (auto& element : my_vector)
{
auto index = std::distance(front, &element);
}
Upvotes: 4
Reputation: 26272
for (range_declaration : range_expression)
loop_statement
is roughly equivalent to this code:
for (auto begin = range_expression.begin(), end = range_expression.end();
begin != end; ++begin)
{
range_declaration = *begin;
loop_statement
}
Note the *
operator. So, range_declaration
is not the iterator, but an element, it points to.
If you need an index, use plain for
loop:
for (std::size_t index = 0; index < my_vector.size(); ++index)
loop_statement
Upvotes: 2