Why use iterators instead of array indices?

前端 未结 27 1885
萌比男神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:21

    I don't think it makes much difference for a vector. I prefer to use an index myself as I consider it to be more readable and you can do random access like jumping forward 6 items or jumping backwards if needs be.

    I also like to make a reference to the item inside the loop like this so there are not a lot of square brackets around the place:

    for(size_t i = 0; i < myvector.size(); i++)
    {
        MyClass &item = myvector[i];
    
        // Do stuff to "item".
    }
    

    Using an iterator can be good if you think you might need to replace the vector with a list at some point in the future and it also looks more stylish to the STL freaks but I can't think of any other reason.

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

    No one mentioned yet that one advantage of indices is that they are not become invalid when you append to a contiguous container like std::vector, so you can add items to the container during iteration.

    This is also possible with iterators, but you must call reserve(), and therefore need to know how many items you'll append.

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

    I always use array index because many application of mine require something like "display thumbnail image". So I wrote something like this:

    some_vector[0].left=0;
    some_vector[0].top =0;<br>
    
    for (int i = 1; i < some_vector.size(); i++)
    {
    
        some_vector[i].left = some_vector[i-1].width +  some_vector[i-1].left;
        if(i % 6 ==0)
        {
            some_vector[i].top = some_vector[i].top.height + some_vector[i].top;
            some_vector[i].left = 0;
        }
    
    }
    
    0 讨论(0)
  • 2020-11-22 16:24

    If you have access to C++11 features, then you can also use a range-based for loop for iterating over your vector (or any other container) as follows:

    for (auto &item : some_vector)
    {
         //do stuff
    }
    

    The benefit of this loop is that you can access elements of the vector directly via the item variable, without running the risk of messing up an index or making a making a mistake when dereferencing an iterator. In addition, the placeholder auto prevents you from having to repeat the type of the container elements, which brings you even closer to a container-independent solution.

    Notes:

    • If you need the the element index in your loop and the operator[] exists for your container (and is fast enough for you), then better go for your first way.
    • A range-based for loop cannot be used to add/delete elements into/from a container. If you want to do that, then better stick to the solution given by Brian Matthews.
    • If you don't want to change the elements in your container, then you should use the keyword const as follows: for (auto const &item : some_vector) { ... }.
    0 讨论(0)
  • 2020-11-22 16:25

    because you are not tying your code to the particular implementation of the some_vector list. if you use array indices, it has to be some form of array; if you use iterators you can use that code on any list implementation.

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

    Several good points already. I have a few additional comments:

    1. Assuming we are talking about the C++ standard library, "vector" implies a random access container that has the guarantees of C-array (random access, contiguos memory layout etc). If you had said 'some_container', many of the above answers would have been more accurate (container independence etc).

    2. To eliminate any dependencies on compiler optimization, you could move some_vector.size() out of the loop in the indexed code, like so:

      const size_t numElems = some_vector.size();
      for (size_t i = 0; i 
    3. Always pre-increment iterators and treat post-increments as exceptional cases.

    for (some_iterator = some_vector.begin(); some_iterator != some_vector.end(); ++some_iterator){ //do stuff }

    So assuming and indexable std::vector<> like container, there is no good reason to prefer one over other, sequentially going through the container. If you have to refer to older or newer elemnent indexes frequently, then the indexed version is more appropropriate.

    In general, using the iterators is preferred because algorithms make use of them and behavior can be controlled (and implicitly documented) by changing the type of the iterator. Array locations can be used in place of iterators, but the syntactical difference will stick out.

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