Why use iterators instead of array indices?

前端 未结 27 1884
萌比男神i
萌比男神i 2020-11-22 15:45

Take the following two lines of code:

for (int i = 0; i < some_vector.size(); i++)
{
    //do stuff
}

And this:

for (som         


        
相关标签:
27条回答
  • 2020-11-22 16:27

    Another nice thing about iterators is that they better allow you to express (and enforce) your const-preference. This example ensures that you will not be altering the vector in the midst of your loop:

    
    for(std::vector<Foo>::const_iterator pos=foos.begin(); pos != foos.end(); ++pos)
    {
        // Foo & foo = *pos; // this won't compile
        const Foo & foo = *pos; // this will compile
    }
    
    0 讨论(0)
  • 2020-11-22 16:28

    Aside from all of the other excellent answers... int may not be large enough for your vector. Instead, if you want to use indexing, use the size_type for your container:

    for (std::vector<Foo>::size_type i = 0; i < myvector.size(); ++i)
    {
        Foo& this_foo = myvector[i];
        // Do stuff with this_foo
    }
    
    0 讨论(0)
  • 2020-11-22 16:29

    For container independence

    0 讨论(0)
  • 2020-11-22 16:31

    You might want to use an iterator if you are going to add/remove items to the vector while you are iterating over it.

    some_iterator = some_vector.begin(); 
    while (some_iterator != some_vector.end())
    {
        if (/* some condition */)
        {
            some_iterator = some_vector.erase(some_iterator);
            // some_iterator now positioned at the element after the deleted element
        }
        else
        {
            if (/* some other condition */)
            {
                some_iterator = some_vector.insert(some_iterator, some_new_value);
                // some_iterator now positioned at new element
            }
            ++some_iterator;
        }
    }
    

    If you were using indices you would have to shuffle items up/down in the array to handle the insertions and deletions.

    0 讨论(0)
  • 2020-11-22 16:31

    Indexing requires an extra mul operation. For example, for vector<int> v, the compiler converts v[i] into &v + sizeof(int) * i.

    0 讨论(0)
  • 2020-11-22 16:32

    The first form is efficient only if vector.size() is a fast operation. This is true for vectors, but not for lists, for example. Also, what are you planning to do within the body of the loop? If you plan on accessing the elements as in

    T elem = some_vector[i];
    

    then you're making the assumption that the container has operator[](std::size_t) defined. Again, this is true for vector but not for other containers.

    The use of iterators bring you closer to container independence. You're not making assumptions about random-access ability or fast size() operation, only that the container has iterator capabilities.

    You could enhance your code further by using standard algorithms. Depending on what it is you're trying to achieve, you may elect to use std::for_each(), std::transform() and so on. By using a standard algorithm rather than an explicit loop you're avoiding re-inventing the wheel. Your code is likely to be more efficient (given the right algorithm is chosen), correct and reusable.

    0 讨论(0)
提交回复
热议问题