Boost logo

Boost Users :

From: David Abrahams (dave_at_[hidden])
Date: 2003-05-19 14:34:20


Tarjei Knapstad <tarjeik_at_[hidden]> writes:

> I encountered the following problem today which I've reduced down to a
> simple example. Basically what I want to do is recurse through a
> typelist (mpl::vector) popping an element each time and end recursion by
> using apply_if with mpl::empty<List> as the condition. I've made a
> simple Reverse class template to illustrate the problem. (The Reverse
> class is of course intended to reverse the contents of a typelist....)
>
> --------------------- begin code ---------------------
>
> #include <boost/mpl/front.hpp>
> #include <boost/mpl/push_back.hpp>
> #include <boost/mpl/pop_front.hpp>
> #include <boost/mpl/apply_if.hpp>
> #include <boost/mpl/empty.hpp>
> #include <boost/mpl/size.hpp>
> #include <boost/mpl/vector.hpp>
>
> using namespace boost::mpl;
>
> template <typename List>
> struct Reverse
> {
> typedef typename front<List>::type FrontElem;
> typedef typename pop_front<List>::type Rest;
> typedef typename apply_if<
> empty<Rest>,
> vector<FrontElem>,
> typename push_back<typename Reverse<Rest>::Type,
> FrontElem>::type
> >::type Type;
> };
>
> typedef vector<int,int,long> List;
> typedef Reverse<List>::Type RevList;
>
> --------------------- end code -----------------------
>
> When attempting to create the RevList type however, gcc spits the
> following at me:
>
> reverse.cpp: In instantiation of
> `boost::mpl::pop_front<boost::mpl::vector0<boost::mpl::void_> >':
> reverse.cpp:15: instantiated from
> `Reverse<boost::mpl::vector0<boost::mpl::void_> >'
> reverse.cpp:21: instantiated from `Reverse<boost::mpl::vector1<long
> int> >'
> reverse.cpp:21: instantiated from `Reverse<boost::mpl::vector2<int,
> long int> >'
> reverse.cpp:21: instantiated from `Reverse<List>'
> reverse.cpp:25: instantiated from here

> reverse.cpp:15: base class `
> boost::mpl::pop_front_traits<boost::mpl::aux::vector_tag<0>
> >::algorithm<boost::mpl::vector0<boost::mpl::void_> >' has incomplete
> type

That line above means that you tried to pop the front element off an
empty vector, and it's easy to see that pop_front<List>::type is
evaluated whether List is empty or not.

Some things to note:

     1. If your algorithm is doing repeated pop_fronts, you probably
        want a list: since each successive list is a sublist of the
        previous one, the new list doesn't cost any instantiations

     2. Barring that, use an iterator_range to avoid instantiating a
        new vector at each iteration

     3. The easy way to do this is

            mpl::fold<
                List
              , mpl::push_front<>
              , typename mpl::clear<List>::type>::type
>

        I believe.

HTH,

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com

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