std::map で remove_if をする

いろいろと考えていたんですが Boost.Range の filter でそれっぽく処理することが出来ました。

[ソース]

#include <boost/range/algorithm/for_each.hpp>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/bind.hpp>
#include <map>
#include <string>
#include <iostream>

bool
over_three(std::pair<int, std::string> const& pair){
    return pair.first >= 3;
}

void
disp(std::pair<int, std::string> const& pair){
    std::cout << pair.first << ":" << pair.second << std::endl;
}

int
main(){
    using boost::adaptors::filter;

    std::map<int, std::string> data;
    data[0] = "zero";
    data[1] = "one";
    data[2] = "two";
    data[3] = "three";
    data[4] = "four";
    data[5] = "five";
    
    // ! を使いたかったので、boost::bind でラップ
    BOOST_AUTO(result_range, filter(data, !boost::bind(&over_three, _1)) );
    std::map<int, std::string> result(result_range.begin(), result_range.end());

    std::cout << ">result" << std::endl;
    boost::for_each(result, disp);
    std::cout << ">data" << std::endl;
    boost::for_each(data, disp);
    
    return 0;
}

[出力]

>result
0:zero
1:one
2:two
>data
0:zero
1:one
2:two
3:three
4:four
5:five

んーこれでいいかしら。
range から map にコピーするのがちょっとめんどくさいですね…。
もっとスマートなやり方はあるかな。

[boost]

  • ver 1.47.0