Range adaptors and compatibility with non-adapted iterators
先日、Boost MLであった話。
map<int, string> m; auto it = find_if(m | map_values, pred); if (it != m.end()) { }
Rangeアダプタ適用結果を用いてイテレータを得た場合、そのイテレータはイテレータアダプタに変換された型となるため、このような書き方をすると、if文のところで、「itの型とm.end()の型が合わない」というコンパイルエラーになってしまう問題があります。
この解決策として私は、イテレータを直接使用せずにoptionalを使う書き方を推奨したのですが、他の方はbase()関数を使用して元のイテレータを取得する方法を提示していました。
#include <iostream> #include <map> #include <boost/range/adaptor/map.hpp> #include <boost/range/algorithm/find_if.hpp> bool is_alice(const std::string& name) { return name == "Alice"; } int main() { std::map<int, std::string> m = {{3, "Alice"}, {1,"Bob"}, {4, "Carol"}}; auto it = boost::find_if(m | boost::adaptors::map_values, is_alice); if (it.base() != m.end()) { std::cout << "found:" << *it << std::endl; } else { std::cout << "not found" << std::endl; } }
found:Alice
こんなことができるとは知らなかった。