GCC 4.5 + Boost 1.42.0 + P-State 1.04.3で以下のコードがコンパイル通りません。
#include <iostream> #include <vector> #include <pstade/oven/filtered.hpp> namespace oven = pstade::oven; template <class R, class F> void for_each(const R& r, F f) { std::for_each(boost::begin(r), boost::end(r), f); } struct is_even { typedef bool result_type; bool operator()(int x) const { return x % 2 == 0; } }; struct disp { typedef void result_type; void operator()(int x) const { std::cout << x << std::endl; } }; int main() { const std::vector<int> v = {1,2,3,4,5}; for_each(v | oven::filtered(is_even()), disp()); // エラー! }
これがエラーになる原因のひとつは、つい先日Boostの開発者MLで上がってたBoost.MPLのADLに関する問題。
【1.43】【beta】 Fix for MPL under gcc 4.5
【MPL】 gcc-4.5 compilation problems related to arity_helper
これは後者のリンク先にあるパッチで改善されます。
この修正がBoost 1.43.0に入るかはどうかは、時期的に難しいかもしれません。
このパッチでだいぶコンパイルエラーがとれるのですが、
いまだに以下のエラーが残っていて原因がいまだわからない状態です。
In file included from /boost/boost_1_42_0/boost/range/iterator.hpp:19:0, from /boost/boost_1_42_0/boost/range/begin.hpp:24, from /pstade/pstade_1_04_3/pstade/oven/filtered.hpp:20, from main.cpp:3: /boost/range/mutable_iterator.hpp: In instantiation of 'boost::range_mutable_iterator<mpl_::arg<-0x000000001> >': /boost/boost_1_42_0/boost/mpl/eval_if.hpp:60:31: instantiated from 'boost::mpl::eval_if_c<false, boost::range_const_iterator<mpl_::arg<-0x000000001> >, boost::range_mutable_iterator<mpl_::arg<-0x000000001> > >' /boost/boost_1_42_0/boost/range/iterator.hpp:63:63: instantiated from 'boost::range_iterator<mpl_::arg<-0x000000001> >' /pstade/pstade_1_04_3/pstade/oven/././range_iterator.hpp:35:1: instantiated from 'pstade::oven::range_iterator<mpl_::arg<-0x000000001> >' /pstade/pstade_1_04_3/pstade/oven/filtered.hpp:44:9: instantiated from 'pstade::oven::filtered_detail::base<mpl_::arg<-0x000000001>, mpl_::arg<-0x000000001> >' main.cpp:28:39: instantiated from here /boost/boost_1_42_0/boost/range/mutable_iterator.hpp:37:52: error: no type named 'iterator' in 'struct mpl_::arg<-0x000000001>'
MPLのプレースホルダーの置き換えがうまくいってなさそうなので、
operator|()ではなく、make_*を使ってみたらそっちはコンパイルが通りました。
#include <iostream> #include <vector> #include <pstade/oven/filtered.hpp> namespace oven = pstade::oven; template <class R, class F> void for_each(const R& r, F f) { std::for_each(boost::begin(r), boost::end(r), f); } struct is_even { typedef bool result_type; bool operator()(int x) const { return x % 2 == 0; } }; struct disp { typedef void result_type; void operator()(int x) const { std::cout << x << std::endl; } }; int main() { const std::vector<int> v = {1,2,3,4,5,6}; for_each(oven::make_filtered(v, is_even()), disp()); // OK }
さて、あとはどこが悪いのだろう。もう3日くらい調べてます。