0

Suppose I have the following containers:

vector<string> input = assign::list_of("one")("two")("three")("four");
vector<map<string, int> > result;

And say I want result to look something like:

{{"one", 1}, {"two", 1}, {"three", 1}, {"four", 1}}

I would like to use an STL algorithm, I think either transform or for_each should be ok. For transform I have the code:

transform(input.begin(), input.end(), back_inserter(result), boost::bind(assign::map_list_of(_1, 1)));

But this yields a compile error along the lines of no type named ‘result_type’ in ‘class boost::assign_detail::generic_list, int> >’

For for_each I have the code:

    for_each(input.begin(), input.end(), 
        boost::bind<void, void(std::vector<std::map<std::string, int> >::*)(const map<string, int>&)>(
            &std::vector<std::map<std::string, int> >::push_back, 
            &result, 
            assign::map_list_of(_1, 1)));

But this yields a compile error which is in summary: no match for call to ‘(boost::_mfi::dm, int>&), std::vector, int> > >) (std::vector, int> >*&, boost::assign_detail::generic_list, int> >&)’

What is the correct way to do this? Please note that I can not use C++11, and I would like to use boost_bind in conjunction with an STL algorithm just for the sake of learning more about boost::bind.


WRT @Joachim's comment about calling map_list_of, I made the following modification:

for_each(input.begin(), input.end(),
        boost::bind<void, void(std::vector<std::map<std::string, int> >::*)(const map<string, int>&)>(
            &std::vector<std::map<std::string, int> >::push_back,
            &result,
            boost::bind<void, map<string, int>(const string&, int)>(&assign::map_list_of, _1, 1));

Which yields the compile error: cannot convert ‘& boost::assign::map_list_of’ (type ‘’) to type ‘std::map, int> (*)(const std::basic_string&, int)’

riQQ
  • 9,878
  • 7
  • 49
  • 66
Tom
  • 6,601
  • 12
  • 40
  • 48
  • By the way, your use of `boost::assign::map_list_of` in your `boost::bind` call is wrong, as you actually *call* the `map_list_of` function, passing its result as the function to call (which of course will give you errors). – Some programmer dude Aug 11 '14 at 14:21

2 Answers2

1

Try this:

#include <boost/assign.hpp>
#include <boost/bind.hpp>
#include <vector>
#include <map>
#include <string>

int main()
{
    std::vector<std::string> input = boost::assign::list_of("one")("two")("three")("four");
    std::vector<std::map<std::string, int> > result;

    for_each
    (
        input.begin()
      , input.end()
      , boost::bind
        (
            static_cast<void(std::vector<std::map<std::string, int> >::*)(const std::map<std::string, int>&)>(&std::vector< std::map<std::string, int> >::push_back)
          , &result
          , boost::bind(&boost::assign::map_list_of<std::string, int>, _1, 1)
        )
    );    

    return 0;    
}
Brandon Kohn
  • 1,612
  • 8
  • 18
0
BOOST_FOREACH(const std::string& str, input)
  result[str] = 1;

I realize this doesn't use STL algorithms and Boost.Bind, but it's concise and intuitive.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • But `result` is not a map, it's a vector. – Some programmer dude Aug 11 '14 at 13:26
  • This doesn't answer the question, as I did specifically say I want to use STL algorithms and bind. – Tom Aug 11 '14 at 13:55
  • 1
    @Tom: well, perhaps if you tell us a bit more about why you have this desire we can help you more. Otherwise, it's hard to get motivated to screw up a perfectly good "for" loop. – John Zwinck Aug 11 '14 at 14:22
  • @JoachimPileborg: You're right, but the OP's example didn't really show a vector of maps either, so.... I suppose we can construct result with `1` then doing `result.front()[str] = 1`. It's not completely clear from the question. – John Zwinck Aug 11 '14 at 14:23
  • @JohnZwinck The question is completely clear as to what I want to achieve, I think my motivation is irrelevant. – Tom Aug 11 '14 at 14:28
  • 4
    @Tom It might help if you tell us about the problem you actually try to solve with your solution. There might be other, maybe even better, solutions. If it's just for fun and learning that's okay too, but then you should at least mention it in the question. Just saying "I have this solution, please help me make it work", without a problem description is not that helpful for us who try to help you. You need to help us to help you. :) Also please read about [the XY problem](http://meta.stackoverflow.com/questions/66377/what-is-the-xy-problem) if you haven't done that yet. – Some programmer dude Aug 11 '14 at 14:33
  • @Tom And as I said, that's fine too. Just remember that even if one fail, one has still learned something. ;) – Some programmer dude Aug 11 '14 at 15:25