web-dev-qa-db-ja.com

std :: list <> :: iteratorの値をポインターに取得していますか?

Stl :: Listを介してループし、後で関数で使用するためにオブジェクトの1つの値を格納するにはどうすればよいですか?

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

どちらか

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

これらは、個人の好みの増加に応じて分類されます。 :)

56
sbi

listの場合、イテレータを無効にする唯一の方法は、eraseを使用することです。したがって、ループのある時点でlist.erase(p1)を呼び出していると思います。イテレータのコピーを作成し、p1を1つ戻してから、コピーを消去する必要があります。

編集:ああ待って、それはそれがコンパイルではないことを意味しましたか?もしそうなら、@ sbiの答えを見てください。しかし、あなたは本当にあなたの質問を良い方法で言葉にする必要があります。コンパイルエラーは何ですか?それとも実行時に失敗しますか?ただし、この場合は、コンパイルエラーを意味します。

1
rlbond

私はSTLの専門家ではありませんが、コンパイルに失敗する理由は、イテレーターが別のオブジェクトを指すオブジェクトであるためです。つまり、イテレータはポインタを一般化したものです。したがって、コードへの最小限の変更で必要なことを行うには、最初にイテレータを逆参照して、そこに含まれる値を取得する必要があります。次に、「&」を使用してそのアドレスを取得し、そのアドレスをポインター変数に割り当てます。これが、ptr =&* itである理由です。動作します。

0
Carl