Boost logo

Boost Users :

From: David Abrahams (dave_at_[hidden])
Date: 2004-12-20 16:47:55


David Greene wrote:
> 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.

insert<_,_> is equivalent to insert<_1,_2>

> 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]

You left out the line that says "error:" and gives the error message.
BTW, I suggest you get STLFilt, which will move this error to the top.

But try using protect<insert<_,_> instead. I'm not sure that lambda<X>
is derived from lambda<X>::type, and even if you used lambda<insert<_,_>
>::type I'm not positive that would work.

> 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.

HTH,

-- 
Dave Abrahams
Boost Consulting
http://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