Boost logo

Boost Users :

From: Christian Henning (chhenning_at_[hidden])
Date: 2007-03-19 16:18:09


Hi there, is it possible to have a stateful functor object when using
fusion::for_each() loop.

I would like to to the following:

#include <vector>

#include <boost/mpl/assert.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/transform.hpp>

#include <boost/fusion/algorithm/transformation/transform.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/sequence/adapted/mpl.hpp>
#include <boost/fusion/sequence/container.hpp>
#include <boost/fusion/sequence/conversion/as_list.hpp>

using namespace std;
using namespace boost;

struct A { void print() { cout << "A" << endl; }};
struct B { void print() { cout << "B" << endl; }};
struct C { void print() { cout << "C" << endl; }};

std::vector<A> find_all( A ) { return std::vector<A>(12); }
std::vector<B> find_all( B ) { return std::vector<B>(12); }
std::vector<C> find_all( C ) { return std::vector<C>(12); }

typedef mpl::list< A, B, C > _types_;

template <typename T>
struct add_vector
{
   typedef std::vector<T> type;
};

struct find_all_
{
   template< class T >
   void operator()( T& t ) const
   {
      typedef typename T::value_type type;
      type v;
      t = find_all( v );
   }
};

struct check_size
{
   check_size()
   : _init( false ), _size( 0 ) {}

   template< class T >
   void operator()( T& t )
   {
      if( !_init )
      {
         _size = t.size();

         _init = true;

         return;
      }

      if( _size != t.size() )
      {
         throw runtime_error( "vectors don't match up." );
      }
   }

private:

   bool _init;
   size_t _size;
};

struct print
{
   template< class T >
   void operator()( T& vec ) const
   {
      vec[0].print();
   }
};

int main()
{
   typedef mpl::transform1< _types_, add_vector<mpl::_1> >::type
_mpl_list_of_vectors_;

   typedef fusion::result_of::as_list<_mpl_list_of_vectors_>::type
_fusion_list_of_vectors_;

   _fusion_list_of_vectors_ vectors;
   fusion::for_each( vectors, find_all_() );

   fusion::for_each( vectors, check_size() );

   return 0;
}

Unfortunately it wont compile. The error messages are:

c:\boost\boost\fusion\algorithm\iteration\detail\for_each.hpp(28) :
error C3848: expression having type 'const check_size' would lose some
const-volatile qualifiers in order to call 'void check_size::operator
()<T>(T &)'
        with
        [
            T=boost::fusion::extension::deref_impl<boost::fusion::cons_iterator_tag>::apply<boost::fusion::cons_iterator<_fusion_list_of_vectors_>>::value_type
        ]
        c:\boost\boost\fusion\algorithm\iteration\for_each.hpp(37) :
see reference to function template instantiation 'void
boost::fusion::detail::for_each<boost::fusion::extension::begin_impl<boost::fusion::cons_tag>::apply<Sequence>::type,boost::fusion::extension::end_impl<boost::fusion::cons_tag>::apply<Sequence>::type,F>(const
First &,const Last &,const F &,boost::mpl::false_)' being compiled
        with
        [
            Sequence=_fusion_list_of_vectors_,
            F=check_size,
            First=boost::fusion::extension::begin_impl<boost::fusion::cons_tag>::apply<_fusion_list_of_vectors_>::type,
            Last=boost::fusion::extension::end_impl<boost::fusion::cons_tag>::apply<_fusion_list_of_vectors_>::type
        ]
        test.cpp(100) : see reference to function template
instantiation 'void
boost::fusion::for_each<_fusion_list_of_vectors_,check_size>(Sequence
&,const F &)' being compiled
        with
        [
            Sequence=_fusion_list_of_vectors_,
            F=check_size
        ]

Any ideas?

Christian


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