reverse_iterator使用時のerase()の仕方
2014.11.01 追記
この記事で不完全なコードを乗せた結果エラーを招きやすい内容となっていたので、別の記事を書き直しております
旧記事
list<Obje> objects;
list<Obje>::iterator objects_i;
for(objects_i = objects.begin(); objects_i != objects.end(); objects_i++)
{
objects_i->draw();
}
だと、前から順に操作してくれるのだけど、OpenGLだとこれであとに書いた物ほど前面に出ることになる。
描画順を逆さにするためにイテレータを逆順に追わせようと
for(objects_i = (--objects.end()); objects_i != (--objects.begin()); objects_i--)
{
objects_i->draw();
}
としてみたのだけど、 "Expression: list iterator not decrementable" とエラーが出て、プログラムが即刻止まる。listはランダムアクセスではないにしても仕様上は--が出来るはずなのだが。
そゆわけで、reverse_iteratorなら逆順に追えるはずなので使うことにする。
list<Obje> objects;
list<Obje>::reverse_iterator objects_ri;
for(objects_ri = objects.rbegin(); objects_ri != objects.rend(); objects_ri++)
{
objects_ri->draw();
}
でとりあえずOKなんだけど、今度はobjectsからひとつのオブジェクトを消そうとした際、erase()関数がreverse_iteratorを引数として使用できないことが判明。
1 番目の引数を 'std::reverse_iterator<_RanIt>' から 'std::list<_Ty>::_Const_iterator<_Secure_validation>' に変換できません。
ときたもので。
そんなわけで、list中の消去対象のオブジェクトを指しているreverse_iteratorを、通常のiteratorに変換する関数 base() というものが使用できることが、ここhttp://blogs.wankuma.com/youchi/archive/2007/09/05/94161.aspxでわかった。
objects.erase((++objects_ri).base());
だそうです。これで、もともとreverse_iteratorのobjects_riが指していたオブジェクトを無事消すことが出来ました。