2010-05-02 5 views
15

Jak mogę przechodzić przez listę stl :: List i zapisywać wartość jednego z obiektów do wykorzystania później w funkcji?Uzyskiwanie wartości std :: list <> :: iterator na wskaźnik?

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

Czy próbujesz powiedzieć, że ten kod się nie kompiluje? '// nie powiedzie się' zwykle oznacza, że ​​masz na myśli błąd podczas działania. – rlbond

+0

@rlbond: Zgadzam się, że '// nie uda się skompilować' byłoby lepsze (chociaż w tym przykładzie zakładałem, że błąd kompilatora nie był niepożądanym efektem ubocznym wklejania kodu), ale nie zgadzam się z tym'// failed' _ "zwykle oznacza błąd czasu wykonywania" _. – sbi

Odpowiedz

53

albo

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

lub

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

lub

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

lub

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

Są one sortowane według rosnących osobistych preferencji. :)

+4

Przewijanie w dół to było naprawdę przyjemne doświadczenie. +1 – Potatoswatter

+0

closestParticle = & * it // Podstęp! Czy możesz zrobić to, co robi się bardziej gadatliwe, czytam to jako: Idź do adresu wskaźnika do iteratora "to"? – Onedayitwillmake

+3

Przyjemny połów. Osobiście wybiorę # 2 jako mój ulubiony wybór. I jestem trochę zdezorientowany z # 3 i # 4. Wygląda na to, że wracasz przedwcześnie. – rlbond

1

Jedynym sposobem unieważnienia iteratora jest go. Podejrzewam, że dzwonisz na list.erase(p1) w pewnym momencie pętli. Musisz wykonać kopię iteratora, przenieść p1 z powrotem, a następnie skasować kopię.

EDYCJA: Oh czekaj, czy miałeś na myśli, że nie kompilować? Jeśli tak, zobacz odpowiedź @ sbi. Ale naprawdę musisz wypowiedzieć swoje pytanie w dobry sposób. Jaki jest twój błąd kompilacji? Czy może zawieść w czasie wykonywania? W tym przypadku jednak uważam, że masz na myśli błąd kompilacji.

+0

Nie jestem pewien, czy odpowiedziałeś na właściwe pytanie Czy coś pominąłem? – sbi

+0

Miałem na myśli błąd kompilatora, mój błąd nie wiedziałem o konwencjach :) - Ten załatwił: closestParticle = &*it; // Więc to mówi? // Przejdź do adresu wskaźnika na nim? – Onedayitwillmake

0

Nie jestem ekspertem od STL, ale uważam, że powodem, dla którego nie udało się skompilować, jest to, że iterator jest obiektem, który wskazuje na inny obiekt. Innymi słowy, iterator jest uogólnieniem wskaźnika. Aby zrobić to, co chcesz, przy minimalnych zmianach w kodzie, najpierw musisz odwołać iterator, aby uzyskać wartość, którą zawiera. Następnie użyjesz "&", aby uzyskać jego adres, a następnie przypisze ten adres do zmiennej wskaźnika. Oto dlaczego ptr = & * it; Prace.