STL list random iterator

Feb 7, 2009 at 5:36am
class A is a user defind class.
if I have list<A*> in my code as follows.

list<A*> m_lstAList;

list<A*>::iterator itSt;
for(itSt = m_lstAList.begin(); itSt != m_lstAList.end(); itSt++)
{
int i = *itSt->GetVal();
int j = -1;
if(itSt != m_lstAList.begin())
{
j = *(itSt - 1)->GetVal();
}
//code proceeds
}

I'm getting an error for the bold face code. Does there any solution so that while traversing through the list in a loop we can take a previous iterator like the code above, instead of creating a temp iterator as follows.

for(itSt = m_lstAList.begin(); itSt != m_lstAList.end(); itSt++)
{
int i = *itSt->GetVal();
int j = -1;
list<A*>::iterator itTemp = itSt;
if(itTemp != m_lstAList.begin())
{
itTemp--;
j = *itTemp->GetVal();
}
//code proceeds
}

If any solution please provide.
Feb 7, 2009 at 6:59am
STL lists only offer bidirectional iterators, not random access iterators. A deque or a vector would let you do that but I would expect that you already chose to use a list for a reason.

Just throw the last iterator in a variable each time threw the loop, you don't have to explicitly back up one every time, then.
Feb 7, 2009 at 7:22am
Sorry for taking this off-topic, but this is a great example of how not to name variables: m_lstAList
Feb 7, 2009 at 3:17pm
You could make a function to do it.

1
2
3
4
5
template< typename Iterator >
Iterator get_rand_iter( Iterator i, ssize_t n ) {
    std::advance( i, n );
    return i;
}


Now just change your boldfaced line to

 
j = *(get_rand_iter( itSt, -1 ) )->GetVal();


You might also consider making the function throw if advancing the iterator would take it beyond the end or beginning.

Be aware that get_rand_iter() as defined now is O(n). [And making the above change would make it 3 times slower.]
Topic archived. No new replies allowed.