boost::remove_erase/boost::remove_erase_if

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