C++標準ライブラリのコンテナ要素を削除するのに、Remove-Eraseイディオムというのがあります。
std::remove()/std::remove_if()アルゴリズムはコンテナから直接要素を削除するのではなく、削除対象の要素を後ろに移動し、削除対象の先頭イテレータを返します。その後、コンテナのメンバ関数であるerase()に削除範囲のイテレータを渡してあげれば削除できます。
#include <iostream> #include <vector> #include <algorithm> int main() { std::vector<int> v = { 1, 2, 3, 4, 5 }; // ここではまだ消さない。削除する要素をずらす。 std::vector<int>::iterator it = std::remove_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; }); // ほんとに削除する v.erase(it, v.end()); for (int x : v) { std::cout << x << std::endl; } }
1 3 5
めんどくさいですね。
Boost.Rangeには、これを同時にやってくれるboost::remove_erase()/boost::remove_erase_if()が用意されています。
#include <iostream> #include <vector> #include <boost/range/algorithm_ext/erase.hpp> int main() { std::vector<int> v = { 1, 2, 3, 4, 5 }; boost::remove_erase_if(v, [](int x) { return x % 2 == 0; }); for (int x : v) { std::cout << x << std::endl; } }
1 3 5
楽ちんになりました。
参照:
boost::remove_erase() - Boost Range Library
boost::remove_erase_if() - Boost Range Library