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
[ツッコミを入れる]