David Greene wrote:
I'm not understanding something about the interaction of map with the algorithms. I've got a map whose value_type is another map. I'd like to iterate through the map entries and add all the "sub-map" entries to the "primary" map. I wrote a little testcase, attached below. When I compile it with g++ 3.3.3, I get this:
<schnipp>
What am I doing wrong?
Much thanks for the help!
-Dave
Here are the things I can find:
#include
#include #include #include #include #include #include #include using namespace boost; using namespace boost::mpl;
struct key1 {}; struct key2 {};
struct entry { typedef map
> types; };
Err, this isn't what you described. Your map has a value_type **with a nested member called types** that is a map.
typedef map
> map_types; typedef fold
::types, First of all, what is this?---------------------^^^^^ inserter<_1, insert<_1, _2> > > >::type result;
I can only assume you meant "::type," which leads to the second problem. 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 >
So that would be the lambda expression you pass to fold. But I would
tend just use a two-level fold:
typedef fold<
map_types // sequence
, map_types // initial state
fold<
get_types< // The ::types member of
value_type< // The "value" component
map_types // (when in map_types)
, _2 // of the outer element being processed
>
>
, _1 // starting with the outer state
, lambda
::type result;
HTH, -- Dave Abrahams Boost Consulting http://www.boost-consulting.com