Boost logo

Boost Users :

Subject: Re: [Boost-users] [MPL] Fold a vector of pairs
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2012-03-14 02:40:09


On Tue, Mar 13, 2012 at 11:13 PM, Peter Nyssen <peter_at_[hidden]> 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



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net