Iterate back

Suppose I have vector<int> myvecone and I want to iterate over all the elements in reverse order. I can come up with several ways to do this:

for (vector<int>::iterator it = myvec.end() - 1; it >= myvec.begin(); --it)
{
    // do stuff here
}

for (vector<int>::reverse_iterator rit = myvec.rbegin(); rit != myvec.rend(); ++rit)
{
    // do stuff here
}

for (int i = myvec.size() - 1; i >= 0; --i)
{
    // do stuff here
}

So my question is when should I use each? Is there any difference? I know that the first is dangerous because if I pass an empty vector, that myvec.end() - 1is undefined, but are there any other dangers or inefficiencies with this?

+5
source share
6 answers

The version reverse_iteratorshows the intention and works in all containers regardless of their contents.

, . >=, .

, i int. , size(). (vector<int>::size_type), , . (0U - 1Funky terminating checks:|)

+11

, . , , , . , reverse_iterator, , , (, . std::copy_backwards).

+7

.

, , if (!myvec.empty()), undefined.

, , vector<int>::size_type size_t, >= 0 , != (size_t)-1 .

, reverse_iterator .

+3

, begin() ( undefined).

reverse_iterator.

, :

for (size_t i = vec.size(); i --> 0; )

, . ( ) .

+2

. , ..

+1

( , ). / , , , myvec.end()-1 :

for (vector<int>::iterator it = myvec.end(); it != myvec.begin(); --it)
{
    // convert the loop controlling iterator to something that points
    //  to the item we're really referring to

    vector<int>::iterator true_it = it;
    --true_it;


    // do stuff here
    //  but always dereference `true_it` instead of `it`
    //  this is essentially similar to the way a reverse_iterator 
    //  generally works

    int& x = *true_it;
}

:

for (vector<int>::iterator it = myvec.end(); it != myvec.begin();)
{
    // decrement `it` before the loop executes rather than after
    //  it a bit non-idiomatic, but works
    --it;

    int& x = *it;

    // do stuff...
}

, ( , - , ), , , - _ , -, reverse_iterator ( reverse_iterator iterator , , reverse_iterators, ). , insert() , :

// if `it` is a reverse iterator, a call to insert might have to look something like:

myvec.insert( --(it.base()), 42 );  // assume that you know the current vector capacity
                                    //  will avoid a reallocation, so the loop 
                                    //  iterators won't be invalidated

// if `it` is a normal iterator...

myvec.insert( it, 42 );
+1

All Articles