$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: David Greene (greened_at_[hidden])
Date: 2004-12-20 16:07:18
David Abrahams wrote:
> So, IIUC, your ForwardOp is trying to use the copy algorithm with an
> inserter to insert each element of the sequence returned by the above
> lambda expression.  One other problem is that insert<_1, _2> will have
> its placeholders substituted immediately as the "fold" is evaluated.  So
> for each step of the copy, the same state and element will be passed.
> You need to protect that placeholder expression from early substitution.
That makes sense (mostly).  I don't quite grok the lambda stuff, _ and
how it gets replaced with the "right" stuff but I guess that's part of
the learning curve.
I had tried writing the get_types metafunction before but it didn't
help.  The lambda part is what I was missing.  Thanks!
[But see below]
>  The easiest way is to transform it into a metafunction class using the
> lambda metafunction:
> 
>    copy<
>        get_types<          // The ::types member of
>            value_type<     // The "value" component
>                 map_types  // (when in map_types)
>               , _2         // of the current element being processed
>            >
>        >
>      , inserter<           // an inserter starting with the outer state
>            _1              // (the sequence being built) as its state.
>          , lambda<         // [preventing early substitution]
>                insert<_,_> // and inserting each element into
>            >               // the inner state
>        >
>    >
I tried this (replacing get_types with get_entries to reduce confusion):
struct entry {
    typedef map<pair<key2, int> > entries;
};
template<typename Entry>
struct get_entries {
    typedef typename Entry::entries type;
};
typedef map<pair<key1, entry> > map_types;
typedef copy<
    get_entries<          // The ::types member of
          value_type<     // The "value" component
             map_types  // (when in map_types)
           , _2         // of the current element being processed
       >
    >
  , inserter<           // an inserter starting with the outer state
       _1              // (the sequence being built) as its state.
     , lambda<         // [preventing early substitution]
          insert<_,_> // and inserting each element into
       >               // the inner state
    >
 > func;
typedef fold<map_types, map_types, func>::type result;
I believe this is equivalent to what you wrote.  I also tried
the nested fold version as well.
Now g++ complains about apply for both versions:
boost-1_32/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp: In 
instantiation of `boost::mpl::apply_wrap2<map_types, map_types, 
boost::mpl::pair<key2, int> >':
[Loads of "instatiated from" messages]
boost-1_32/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp:49: 
instantiated from `boost::mpl::apply2<func, map_types, 
boost::mpl::pair<key1, entry> >'
boost-1_32/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp:49: 
instantiated from `boost::mpl::aux::fold_impl<1, 
boost::mpl::m_iter<map_types, 2, 3>, boost::mpl::m_iter<map_types, 3, 
3>, map_types, func>'
boost-1_32/boost/mpl/fold.hpp:39:   instantiated from 
`boost::mpl::fold<map_types, map_types, func>'
fold2.cc:51:   instantiated from here
boost-1_32/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp:49: error: no
    class template named `apply' in `struct map_types'
There are other errors but I'm not sure how useful they are.
Thanks for your patience.  I'm just getting back into MPL
after about a year after being off-list.
                        -Dave