2010-05-02 2 views
15

Как я могу пройти через stl :: List и сохранить значение одного из объектов для использования позже в функции?Получение значения std :: list <> :: iterator для указателя?

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

Вы пытаетесь сказать, что этот код не компилируется? '// fail' обычно означает, что вы имеете в виду ошибку времени выполнения. – rlbond

+0

@rlbond: Я согласен, что '// не скомпилировать' было бы лучше (хотя в этом примере я предположил, что ошибка компилятора не была нежелательным побочным эффектом вставки кода), но я бы не согласился с тем, что'// fail' _ "обычно подразумевает ошибку времени выполнения" _. – sbi

ответ

53

Либо

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

или

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

или

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(); 
} 

или

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

Пользователи сортированы по возрастанию. :)

+4

Прокрутка вниз, что было на самом деле приятным опытом. +1 – Potatoswatter

+0

closeestParticle = & * it // Сделал трюк! Не могли бы вы сделать то, что он делает более подробно, я читаю его как: Перейдите по адресу указателя на итератор 'it'? – Onedayitwillmake

+3

Nice catch. Я лично выбрал №2 в качестве своего выбора. И я немного смущен # 3 и # 4. Кажется, ты возвращаешься преждевременно. – rlbond

1

Для list, единственный способ аннулировать итератор - erase. Поэтому я подозреваю, что вы вызываете list.erase(p1) в какой-то момент цикла. Вам нужно сделать копию итератора, переместить p1 назад, а затем удалить копию.

EDIT: О, подождите, вы имели в виду, что это не компилировать? Если да, см. Ответ @ sbi. Но вам действительно нужно правильно рассказать о своем вопросе. Какова ваша ошибка компиляции? Или это не работает во время выполнения? В этом случае, однако, я считаю, что вы имеете в виду ошибку компиляции.

+0

Я не уверен, что вы ответили на правильный вопрос. Пропустил ли я что-нибудь? – sbi

+0

Я имел в виду ошибку компилятора, моя ошибка я не знал об условностях :) - Этот сделал трюк: closeestParticle = &*it; // Так что это говорит? // Идите к адресу указателя на нем? – Onedayitwillmake

0

Я не эксперт по STL, но я считаю, что причина, по которой он не скомпилирован, заключается в том, что итератор является объектом, который указывает на другой объект. Другими словами, итератор является обобщением указателя. Поэтому, чтобы делать то, что вы хотели бы с минимальными изменениями в вашем коде, вам сначала нужно снять ссылку на итератор, чтобы получить значение, которое оно содержит. Затем вы должны использовать «&», чтобы получить его адрес, а затем присвоить этот адрес переменной вашего указателя. Вот почему ptr = & * it; работает.

Смежные вопросы