Boost logo

Boost Users :

From: David Greene (greened_at_[hidden])
Date: 2004-12-20 17:04:39


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

Actually, I didn't leave it out:

boost-1_32/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp:49: error: no
    class template named `apply' in `struct map_types'

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

You're right, that doesn't work:

/cray/iss/compiler/cost/tools/nv1-cray-unicosmp/include/boost-1_32/boost/mpl/aux_/insert_impl.hpp:
In instantiation of `boost::mpl::clear<mpl_::_>':
/cray/iss/compiler/cost/tools/nv1-cray-unicosmp/include/boost-1_32/boost/mpl/aux_/insert_impl.hpp:54:
   instantiated from
`boost::mpl::insert_impl<boost::mpl::non_sequence_tag>::apply<mpl_::_,
mpl_::_, mpl_::na>'
fold3.cc:45: instantiated from `boost::mpl::insert<mpl_::_, mpl_::_,
mpl_::na>'
fold3.cc:45: instantiated from here
/cray/iss/compiler/cost/tools/nv1-cray-unicosmp/include/boost-1_32/boost/mpl/aux_/insert_impl.hpp:54:
error: base
    class
`boost::mpl::clear_impl<boost::mpl::non_sequence_tag>::apply<mpl_::_>'
    has incomplete type

Unfortunately, neither does using protect:

/cray/iss/compiler/cost/tools/nv1-cray-unicosmp/include/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> >'
/cray/iss/compiler/cost/tools/nv1-cray-unicosmp/include/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>'
/cray/iss/compiler/cost/tools/nv1-cray-unicosmp/include/boost-1_32/boost/mpl/fold.hpp:39:
   instantiated from `boost::mpl::fold<map_types, map_types, func>'
fold3.cc:50: instantiated from here
/cray/iss/compiler/cost/tools/nv1-cray-unicosmp/include/boost-1_32/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp:49:
error: no
    class template named `apply' in `struct
    boost::mpl::lambda<boost::mpl::protect<boost::mpl::insert<mpl_::_,
mpl_::_,
    mpl_::na>, 0>, mpl_::void_, mpl_::int_<1> >'

I'll have to get STLFilt. Any hints on the above?

                            -Dave


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