$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Aleksey Gurtovoy (agurtovoy_at_[hidden])
Date: 2004-12-21 05:06:54
David Abrahams writes:
> Oh, I see it now; you're trying to get the "types" member out of the
> result of invoking value_type.  Okay, to do that you need a metafunction
> that gets the types member:
> 
>    template <class Value>
>    struct get_types
>    {
>         typedef Value::types type;
>    };
> 
> now you can write:
> 
>    get_types<          // The ::types member of
>        value_type<     // The "value" component
>             map_types  // (when in map_types)
>          , _2          // of the current element being processed
>        >
>    >
> 
> 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.
>  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
>        >
>    >
Won't work. The 'lambda' metafunction doesn't have any special status here. 
For instance, 'lambda<_1>' is a regular, well, lambda expression, not 
different from, let's say, 'first<_1>'. It's all documented in the 
reference manual, and illustrated by the corresponding tests 
(e.g. http://cvs.sourceforge.net/viewcvs.py/boost/boost/libs/mpl/test/apply.cpp?view=markup).
Answering the OP question: MPL lambda expressions do not support scopes (yet),
so it's not possible to implement the above without an auxiliary metafunction 
incapsulating the nested scope. Which actually might be a good thing -- it's 
hard to imagine that the "inline" version would be shorter and easier to 
understand than this:
    template< typename Map, typename Entry >
    struct copy_entires
        : copy< 
              typename Entry::second::entries
            , inserter<Map, insert<_1,_2> >
            >
    {
    };
    typedef fold<map_types, map_types, copy_entires<_1,_2> >::type result;
-- Aleksey Gurtovoy MetaCommunications Engineering