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 com开发者_开发知识库piler 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?
You should use std::vector<T>::size_type
1. 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)
{
}
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.
If you are just using it for iteration, then you might want to use:
typedef std::vector<Element*> ElementContainer;
ElementContainer myVector(3);
for (ElementContainer::const_iterator cit = myVector.begin();cit != myVector.end(); ++cit)
{
Element* e = *cit;
}
This has the advantage of being slightly more robust to changing from vector<>
to another container.
Just use unsigned
. With size_t
you never remember what the right header to include is, and with vector<T>::size_type
you end up typing too much. For all practical purposes they are the same thing, just retypedef
ed a dozen of times.
精彩评论