tags:

views:

427

answers:

3

I have a boost::bimap and I want to iterate over all positions to add the values of the given side to another STL-compatible container. How can I do this?

My approach was to use std::for_each together with boost::bind:

std::for_each(mybimap.left.begin(),
              mybimap.left.end(),
              boost::bind(&vector::push_back, &myvec,
                boost::bind( ... )));
+1  A: 

Judging from the code you posted it looks like you want to copy everything from boost::bimap to a std::vector.

Try this:

          std::copy(mybimap.left.begin(),
                    mybimap.left.end(),
                    std::back_inserter(myvec));
Edison Gustavo Muenz
This does not work. I decided to use a classic for-loop to interate over the given elements.
Jens
+3  A: 

This should work:

  std::for_each(mybimap.left.begin(),
                mybimap.left.end(),
                boost::bind(&vector_type::push_back, &myvec,
                   boost::bind(&map_type::left_map::value_type::second, _1)));

... or if you mean the key values mapped from instead of the values being mapped to, use first instead of second.

EDIT: I find this double-bind rather clumsy, and the for_each a non-optimal algorithm (copy would be better suited, IMHO the algorithm name should state the intent and that's clearly a copy here). You could also use a transform iterator here:

std::copy(boost::make_transform_iterator(mybimap.left.begin(), select_second()),
          boost::make_transform_iterator(mybimap.left.end(), select_second()),
          std::back_inserter(myvec));

where select_second would be a function object that selects the second element of a pair - or just the boost::bind(&map_type::left_map::value_type::second, _1).

For a situation where I couldn't use a transform_iterator I have written a transform_back_inserter at work which is basically a back_inserter that takes an unary function that is applied to the element before writing (no rocket science to write) - then it would look like

std::copy(mybimap.left.begin(),
          mybimap.left.end(),
          transform_back_inserter(myvec, select_second()));

which I tend to prefer to the transform_iterator when possible as I don't have to repeat the unary function name.

Rüdiger Hanke
A: 
Try &vector<your_value_type>::push_back instead.
Marcus Lindblom