Default values for range access adaptors?
Rangeの先頭要素にアクセスするアダプターで、アクセスできなかった場合にデフォルト値を指定させてほしい、というリクエストがありました。
Ovenから移植し、Boost.Rangeの拡張として開発しているOvenToBoostのfrontアクセッサーは参照を返すので、値(not 参照)であるデフォルト値を許可するのは難しいです。なので、optionalを返すoptional_frontを実装しました。
#include <iostream> #include <vector> #include <boost/assign/list_of.hpp> #include <boost/range/adaptor/filtered.hpp> #include <boost/range/access/front.hpp> bool is_even(int x) { return x % 2 == 0; } int main() { using namespace boost::adaptors; using namespace boost::range::access; std::vector<int> v = boost::assign::list_of(1)(2)(3); if (boost::optional<int&> x = v | filtered(is_even) | optional_front) { std::cout << x.get() << std::endl; } else { std::cout << "not found" << std::endl; } }
2
同様に、最後尾要素にアクセスするoptional_back、ランダムアクセスするoptional_atも実装してあります。
Michel Morinさんから、他のアダプターとの一貫性のために、frontはsingle rangeを返すべきじゃないか、というフィードバックをもらいました。たしかに、optionalの代わりにrangeを返す方法もありだと思います。
for (T x : r | front) {
std::cout << x << std::endl;
}
この設計にすれば、要素にアクセスできたらその要素がfor文で1回だけ取得され、アクセスできなかったら空のrangeが返されます。
設計的にはこの選択肢もありだと思いますが、既存の設計のfrontとoptional_rangeも便利だと思うので、これらに加えてfront_rangeを追加しようと考えています。
なお、OvenToBoostプロジェクトは間もなくBoost.Rangeにマージされる予定になっています。
Time to merge Oven-to-Boost Extensions?
今月中にはマージしてくれるそうです。優先度の高いものから順次入れていくそうなので、私の方も引き続き追加機能の実装を進めていくつもりです。