パーティクル システムでは、パーティクルが十分に古くなると、消滅する必要があります。std::vector
それらはXCodeでかなりうまく機能するアプローチに格納されているため、次のとおりです。
for(std::vector<Particle*>::reverse_iterator iter = particles.rbegin(); iter != particles.rend(); ++iter) {
(*iter)->update();
if ( (*iter)->isDead() ) {
delete (*iter);
particles.erase( --iter.base() );
}
}
Windows を起動し、Visual Studio 2010 でコンパイルした後、動作しないことがわかりました。こちらを参照してください。答え自体が述べているように、これは連想コンテナでは機能しません。ここで最もイライラするのはstd::reverse_iterator
、std::iterator
動作が異なることです。
.erase
をとらずreverse_iterator
、本物を望んでいます (例: thisを参照)rev_it.base()
呼び出しは消去呼び出しでデクリメントする必要があります- 消去した後、をに変換する必要があり
std::iterator
ますstd::reverse_iterator
forward を使用することを考えましたstd::iterator
が、これはひどいアイデアですが、逆方向に反復する必要があるのは、実際には、ループが erased の隣接するメンバーをスキップしないようにすることparticles
です。
ただし、私にとって理にかなっているのは、呼び出しが行われた場合に反復しないことです.erase()
。
for( std::vector<Particle*>::iterator iter = particles.begin(); iter != particles.end(); ) {
(*iter)->update();
if ( (*iter)->isDead() ) {
delete (*iter);
iter = particles.erase(iter);
} else {
++iter;
}
}
これはコンパイルされ、機能し、問題にはならないようです。ただし、問題は次のとおりです。
これを特にばかげた考えにする何かを見落としていますか?
(関数の値iter
を利用することで正しい次の値を指すと確信しており、呼び出しよりも読みやすいようです。).erase()
return
--iter.base()
その括弧はさておき、思い浮かぶロシアのことわざは、「熱い牛乳で火傷を負った者は冷たい水で吹く」です。