2019年05月08日(水) [長年日記]
■ [c++] reverse_iteratorが指す要素の削除
reverse_iteratorが指す要素の削除方法をメモしておく。Effective STLの第28項「reverse_iteratorの基底iteratorの使い方を理解しよう」に説明がある。
- コンテナのerase()メソッドはreverse_iteratorを受け付けないので、reverse_iteratorのbase()メソッドによりiteratorオブジェクトを取得する必要がある。
- base()が返すイテレータが指す要素はreverse_iteratorが指す要素からend()方向に1つずれているので、erase()に渡す際にはイテレータの位置を調整する必要がある。調整には (++rit).base() のようにreverse_iteratorを1つ進めてからbase()を呼ぶべしとEffective STLにある。
rend() rit rbegin() +-------+-------+-----+-------+-------+-----+-------+-------+ | a | b | ... | h | i | ... | y | z | +-------+-------+-----+-------+-------+-----+-------+-------+ begin() rit.base() end()
#include <algorithm> #include <iostream> #include <numeric> #include <vector> int main() { std::vector<int> v(10); std::iota(v.begin(), v.end(), 1); auto rit = std::find_if( v.rbegin(), v.rend(), [](int i) { return i % 3 == 0; }); if (rit != v.rend()) { // reverse_iterator::base()が返すイテレータは指す要素が異なるので調整が必要 // see Effective STL 第28項 v.erase((++rit).base()); } for (const auto& e : v) { std::cout << e << " "; } std::cout << std::endl; }
1 2 3 4 5 6 7 8 10