自習室

こもります

reverse_iterator使用時のerase()の仕方

2014.11.01 追記

この記事で不完全なコードを乗せた結果エラーを招きやすい内容となっていたので、別の記事を書き直しております


改善版 reverse_iterator 使用中のerase()の仕方 - 自習室

旧記事

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が指していたオブジェクトを無事消すことが出来ました。