Tom
Tom

Reputation: 6971

Boost bind and assign to convert vector to a string

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)’

Upvotes: 0

Views: 595

Answers (2)

Brandon Kohn
Brandon Kohn

Reputation: 1621

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;    
}

Upvotes: 1

John Zwinck
John Zwinck

Reputation: 249123

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.

Upvotes: 0

Related Questions