tags:

views:

364

answers:

3

How can i loop thru a stl::List and store the value of one of the objects for use later in the function?

Particle *closestParticle;
for(list<Particle>::iterator p1 = mParticles.begin(); p1 != mParticles.end(); ++p1 )
     {
      // Extra stuff removed
            closestParticle = p1; // fails to compile (edit from comments)
     }
+10  A: 

Either

Particle *closestParticle;
for(list<Particle>::iterator it=mParticles.begin(); it!=mParticles.end(); ++it)
    {
      // Extra stuff removed
            closestParticle = &*it;
    }

or

list<Particle>::iterator closestParticle;
for(list<Particle>::iterator it=mParticles.begin(); it!=mParticles.end(); ++it )
    {
      // Extra stuff removed
            closestParticle = it;
    }

or

inline list<Particle>::iterator findClosestParticle(list<Particle>& pl)
{
    for(list<Particle>::iterator it=pl.begin(); it!=pl.end(); ++it )
        {
          // Extra stuff removed
               return it;
        }
}

or

template< typename It > 
inline It findClosestParticle(It begin, It end)
{
    while(begin != end )
        {
          // Extra stuff removed
               return it;
          ++it;
        }
}

These are sorted in increasing personal preference. :)

sbi
Scrolling down that was actually an enjoyable experience. +1
Potatoswatter
Onedayitwillmake
Nice catch. I'd personally pick #2 as my flavor of choice. And I'm a little confused with #3 and #4. It seems like you're returning prematurely.
rlbond
@rlbond, `rbegin()` !
Johannes Schaub - litb
sbi
@rlbond: I was presuming that `// Extra stuff removed` would be some conditional statement finding the best. Now that I think about it, the algorithm probably needs to traverse __all__ objects in the sequence, so premature return wouldn't bring anything.
sbi
@sbiThat does explain, but to be sure more detail is ALWAYS appreciated!-
Onedayitwillmake
@Johannes: I have no idea what you're trying to tell with hinting at `rbegin()`. Knowing you I assume it's probably a great insight, but it went right over me head. `:(` I'm afraid you're presuming I thought about something you considered, and when I understand the hint I'll have to tell you that I utterly failed to think about it...
sbi
@sbi i wanted to say that using `rbegin` and `rend` will do the equivalent to his loop (assuming the commentar expands to nothing). I.e it will exit at the last item matching, not the first. Nothing really important tho.
Johannes Schaub - litb
@Johannes: I never assumed the comment would expand to nothing...
sbi
A: 

For a list, the only way to invalidate an iterator is to erase it. So I suspect you're calling list.erase(p1) at some point in the loop. You need to make a copy of the iterator, move p1 back one, and then erase the copy.

EDIT: Oh wait, did you mean it doesn't compile? If so, see @sbi's answer. But you really need to word your question in a good way. What is your compile error? Or does it fail at run-time? In this case, however, I believe you mean a compile error.

rlbond
I'm not sure you answered to the right question. Did I miss anything?
sbi
I meant compiler error, my mistake I was unaware of the conventions :)-This one did the trick:closestParticle = // So it's saying? // Go to the address of the the pointer at it?
Onedayitwillmake
A: 

I'm not an expert on the STL, but I believe the reason it fails to compile is because an iterator is an object that points to another object. In other words, an iterator is a generalization of a pointer. So to do what you'd want with minimal changes to your code, you would first need to de-reference the iterator to get at the value it contains. You'd then use the '&' to get its address and would then assign that address to your pointer variable. This is why ptr=&*it; works.

carleeto