Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What should be the index type when iterating over the elements of a vector? [duplicate]

I usually iterate over a vector that way:

for (int i = 0; i < myVector.size(); i++) {
    Element* e = myVector[i];
}

But then the compiler usually gives me this warning:

warning: C4018: '<' : signed/unsigned mismatch

So if an int is not right, which type should the index be? vector::size() seems to be of a "size_type" type, but I'd rather use a more meaningful type. Any suggestion?

like image 557
laurent Avatar asked Aug 10 '11 06:08

laurent


2 Answers

You should use std::vector<T>::size_type1. Its unsigned integral type. Its usually same as size_t.

To know the difference between size_type and size_t, see this topic:

  • C++ for-loop - size_type vs. size_t

1. Similarly, you can use std::string::size_type, std::list<T>::size_type, std::deque<T>::size_type, std::set<T>::size_type, and so on. Almost all standard containers define a nested type called size_type.


One can argue that you should use iterator instead of index. But I also see that sometime iterator makes the for-loop very wide horizontally, see this :

for(std::vector<std::vector<std::string> >::iterator it = v.begin(); it != v.end(); ++it)
{
}

It doesn't look. It in fact irritates sometimes. In such situations, some programmers prefers index over iterator.

In C++0x, iterator has been made more idiomatic. Now you can use iterator without making the syntax cumbersome:

for(auto it = v.begin(); it != v.end(); ++it)
{  
}

Or even better, using range-based for loop:

for(auto & item : v)
{
}
like image 66
Nawaz Avatar answered Oct 05 '22 19:10

Nawaz


The compiler gives the warning because your int is signed but size() returns an unsigned int of type size_t. You don't want this kind of mismatch because it can cause headaches if your int is negative. You can avoid all of this by using size_t.

like image 40
mwd Avatar answered Oct 05 '22 18:10

mwd