[MPL] Fold a vector of pairs
Hi all, I'm trying to understand how to use mpl::fold to transform a vector like this: vector< pair<tag1, A> pair<tag2, B> pair<tag1, C>
into the following: pair< vector<A,C> vector<B>
Following test program fails to compile and I don't understand why. If you could explain me what I'm missing here, you will gain my eternal respect. Kind regards, Peter //-------------------------------------------- #include <boost/mpl/if.hpp> #include <boost/mpl/int.hpp> #include <boost/mpl/fold.hpp> #include <boost/mpl/pair.hpp> #include <boost/mpl/push_back.hpp> #include <boost/mpl/vector.hpp> namespace mpl = boost::mpl; struct tag1 {}; struct tag2 {}; template <typename T> struct is_tag1 : boost::false_type {}; template <> struct is_tag1<tag1> : boost::true_type {}; int main() { typedef mpl::vector< mpl::pair<tag1, mpl::int_<1> >, mpl::pair<tag2, mpl::int_<2> >, mpl::pair<tag1, mpl::int_<3> >
initial_vector;
typedef typename mpl::fold< initial_vector, mpl::pair<mpl::vector<>, mpl::vector<> >, mpl::if_< is_tag1<mpl::first<mpl::_2>::type >, mpl::push_back< mpl::first<mpl::_1>::type, mpl::second<mpl::_2>::type
, mpl::push_back< mpl::second<mpl::_1>::type, mpl::second<mpl::_2>::type
::type sorted_pair;
return 0; } //-------------------------------------------- *$* g++ -Wall -I ../boost/ -o test test.cpp In file included from test.cpp:5:0: ../boost/boost/mpl/pair.hpp: In instantiation of 'boost::mpl::first<mpl_::arg<2> >': test.cpp:32:40: instantiated from here ../boost/boost/mpl/pair.hpp:43:31: fout: no type named 'first' in 'struct mpl_::arg<2>' test.cpp: In functie 'int main()': test.cpp:32:47: fout: template argument 1 is invalid In file included from test.cpp:5:0: ../boost/boost/mpl/pair.hpp: At global scope: ../boost/boost/mpl/pair.hpp: In instantiation of 'boost::mpl::first<mpl_::arg<1> >': test.cpp:34:36: instantiated from here ../boost/boost/mpl/pair.hpp:43:31: fout: no type named 'first' in 'struct mpl_::arg<1>' ../boost/boost/mpl/pair.hpp: In instantiation of 'boost::mpl::second<mpl_::arg<2> >': test.cpp:35:37: instantiated from here ../boost/boost/mpl/pair.hpp:56:32: fout: no type named 'second' in 'struct mpl_::arg<2>' test.cpp: In functie 'int main()': test.cpp:36:13: fout: template argument 1 is invalid test.cpp:36:13: fout: template argument 2 is invalid In file included from test.cpp:5:0: ../boost/boost/mpl/pair.hpp: At global scope: ../boost/boost/mpl/pair.hpp: In instantiation of 'boost::mpl::second<mpl_::arg<1> >': test.cpp:38:37: instantiated from here ../boost/boost/mpl/pair.hpp:56:32: fout: no type named 'second' in 'struct mpl_::arg<1>' test.cpp: In functie 'int main()': test.cpp:40:13: fout: template argument 1 is invalid test.cpp:40:13: fout: template argument 2 is invalid test.cpp:41:9: fout: template argument 1 is invalid test.cpp:41:9: fout: template argument 2 is invalid test.cpp:41:9: fout: template argument 3 is invalid test.cpp:42:5: fout: template argument 3 is invalid test.cpp:42:24: fout: invalid type in declaration before ';' token **
On Tue, Mar 13, 2012 at 11:13 PM, Peter Nyssen <peter@dynsws.com> wrote:
Hi all,
I'm trying to understand how to use mpl::fold to transform a vector like this: vector< pair<tag1, A> pair<tag2, B> pair<tag1, C>
into the following: pair< vector<A,C> vector<B>
Following test program fails to compile and I don't understand why. If you could explain me what I'm missing here, you will gain my eternal respect.
Kind regards, Peter
//--------------------------------------------
#include <boost/mpl/if.hpp> #include <boost/mpl/int.hpp> #include <boost/mpl/fold.hpp> #include <boost/mpl/pair.hpp> #include <boost/mpl/push_back.hpp> #include <boost/mpl/vector.hpp>
namespace mpl = boost::mpl;
struct tag1 {}; struct tag2 {};
template <typename T> struct is_tag1 : boost::false_type {};
template <> struct is_tag1<tag1> : boost::true_type {};
int main() { typedef mpl::vector< mpl::pair<tag1, mpl::int_<1> >, mpl::pair<tag2, mpl::int_<2> >, mpl::pair<tag1, mpl::int_<3> > > initial_vector;
typedef typename mpl::fold< initial_vector, mpl::pair<mpl::vector<>, mpl::vector<> >, mpl::if_< is_tag1<mpl::first<mpl::_2>::type >, mpl::push_back< mpl::first<mpl::_1>::type, mpl::second<mpl::_2>::type >, mpl::push_back< mpl::second<mpl::_1>::type, mpl::second<mpl::_2>::type > > >::type sorted_pair;
Try removing all the ::type's in the fold operation and rely on lazy evaluation. mpl:first< mpl::_1 >::type is equivalent to mpl::_1::first, which of course doesn't exist and isn't what you want; but mpl::first< mpl::_1 > is a placeholder expression equivalent to the mapping ( T0, ... ) -> T0::first, which looks like what you want.
return 0; }
//--------------------------------------------
*$* g++ -Wall -I ../boost/ -o test test.cpp In file included from test.cpp:5:0: ../boost/boost/mpl/pair.hpp: In instantiation of ‘boost::mpl::first<mpl_::arg<2> >’: test.cpp:32:40: instantiated from here ../boost/boost/mpl/pair.hpp:43:31: fout: no type named ‘first’ in ‘struct mpl_::arg<2>’
:: cough ::
test.cpp: In functie ‘int main()’: test.cpp:32:47: fout: template argument 1 is invalid In file included from test.cpp:5:0: ../boost/boost/mpl/pair.hpp: At global scope: ../boost/boost/mpl/pair.hpp: In instantiation of ‘boost::mpl::first<mpl_::arg<1> >’: test.cpp:34:36: instantiated from here ../boost/boost/mpl/pair.hpp:43:31: fout: no type named ‘first’ in ‘struct mpl_::arg<1>’ ../boost/boost/mpl/pair.hpp: In instantiation of ‘boost::mpl::second<mpl_::arg<2> >’: test.cpp:35:37: instantiated from here ../boost/boost/mpl/pair.hpp:56:32: fout: no type named ‘second’ in ‘struct mpl_::arg<2>’ test.cpp: In functie ‘int main()’: test.cpp:36:13: fout: template argument 1 is invalid test.cpp:36:13: fout: template argument 2 is invalid In file included from test.cpp:5:0: ../boost/boost/mpl/pair.hpp: At global scope: ../boost/boost/mpl/pair.hpp: In instantiation of ‘boost::mpl::second<mpl_::arg<1> >’: test.cpp:38:37: instantiated from here ../boost/boost/mpl/pair.hpp:56:32: fout: no type named ‘second’ in ‘struct mpl_::arg<1>’ test.cpp: In functie ‘int main()’: test.cpp:40:13: fout: template argument 1 is invalid test.cpp:40:13: fout: template argument 2 is invalid test.cpp:41:9: fout: template argument 1 is invalid test.cpp:41:9: fout: template argument 2 is invalid test.cpp:41:9: fout: template argument 3 is invalid test.cpp:42:5: fout: template argument 3 is invalid test.cpp:42:24: fout: invalid type in declaration before ‘;’ token
See if that helps. (Too lazy to try it on my own.) - Jeff
participants (2)
-
Jeffrey Lee Hellrung, Jr.
-
Peter Nyssen