I'm trying to compile the Statemachine example from boost-mpl (located in libs/mpl/examples/fsm/player2.cpp), but it fails with boost version 1.37 and g++ 4.8.2. With boost version 1.56 and the same compiler, the build succeeds. Unfortunately, due to some platform constraints, I cannot switch to version 1.56.
I'm not expecting anyone to look into the above mentioned lengthy example, therefore I identified a minimal code snippet which illustrates the problem:
#include <boost/mpl/fold.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/placeholders.hpp>
namespace mpl = boost::mpl;
using namespace mpl::placeholders;
//Basic queue datatype
template< class CURRENT, class NEXT >
struct queue_element
{
typedef typename CURRENT::mytype mytype;
};
//type to be put at the end of the queue
struct default_queue_element
{
};
template <class TYPE>
struct wrapper{
typedef TYPE mytype;
};
typedef mpl::vector<wrapper<int>, wrapper<char> > myvector;
//the following fold expression should create this type:
typedef queue_element<wrapper<char>, queue_element<wrapper<int>,
default_queue_element> > this_type_should_be_created;
//This typedef fails to compile with boost Version 1.37,
//but works perfectly with version 1.56
typedef typename
mpl::fold<
myvector
,default_queue_element
,queue_element<_2,_1>
>::type
generate_queue;
With boost 1.37, g++ issues the following errors:
foldtest2.cpp: In instantiation of ‘struct queue_element<mpl_::arg<2>, mpl_::arg<1> >’:
../boost_1_37_0/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp:85:5: required from ‘const int boost::mpl::aux::template_arity_impl<queue_element<mpl_::arg<2>, mpl_::arg<1> >, 1>::value’
../boost_1_37_0/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp:93:5: required from ‘const int boost::mpl::aux::template_arity<queue_element<mpl_::arg<2>, mpl_::arg<1> > >::value’
../boost_1_37_0/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp:98:30: required from ‘struct boost::mpl::aux::template_arity<queue_element<mpl_::arg<2>, mpl_::arg<1> > >’
../boost_1_37_0/boost/mpl/aux_/preprocessed/gcc/apply.hpp:67:8: required from ‘struct boost::mpl::apply2<queue_element<mpl_::arg<2>, mpl_::arg<1> >, default_queue_element, wrapper<int> >’
../boost_1_37_0/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp:67:85: required from ‘struct boost::mpl::aux::fold_impl<2, boost::mpl::v_iter<boost::mpl::vector<wrapper<int>, wrapper<char> >, 0l>, boost::mpl::v_iter<boost::mpl::vector<wrapper<int>, wrapper<char> >, 2l>, default_queue_element, queue_element<mpl_::arg<2>, mpl_::arg<1> > >’
../boost_1_37_0/boost/mpl/fold.hpp:39:18: required from ‘struct boost::mpl::fold<boost::mpl::vector<wrapper<int>, wrapper<char> >, default_queue_element, queue_element<mpl_::arg<2>, mpl_::arg<1> > >’
foldtest2.cpp:39:6: required from here
foldtest2.cpp:15:38: error: no type named ‘mytype’ in ‘struct mpl_::arg<2>’
typedef typename CURRENT::mytype mytype;
Is there a work-around to make the code compile with boost 1.37? I have been searching the web for quite some time. If nevertheless the question has already been answered somewhere, I would be grateful if you could point that out.
Looks to be very simply a bug in that ancient(¹) version of boost.
A quick bisection tells me it was fixed in v1.43.0(²). Release notes don't disclose the secret, but git does:
It clearly appears to be the latter (confirmed by compiling against 31a2c78).
So your fix this single line in include/boost/mpl/aux_/template_arity.hpp(³):
sizeof(arity_helper(type_wrapper<F>(),arity_tag<N>())) - 1
should be
sizeof(::boost::mpl::aux::arity_helper(type_wrapper<F>(),arity_tag<N>())) - 1
Of course the proper way to fix this is to use a supported version of boost
¹ (November 3rd, 2008)!!
² (May 6th, 2010)
³ warning: also present in several copies generated in preprocessed versions of the header