
Tarjei Knapstad <tarjeik@chemcon.no> 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