开发者

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

This question already has answers here: Iteration over std::vector: unsigned vs signed index variable (18 answers) Closed 7 years ago.

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_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)
{
}


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 retypedefed a dozen of times.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜