calling map::insert through bind.

View: New views
3 Messages — Rating Filter:   Alert me  

calling map::insert through bind.

by Minkoo Seo :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi list.

I've got a question on calling map::insert using bind. What I'd like to
do is to copy all members in m into m2:

#include <iostream>
#include <algorithm>
#include <map>
#include <utility>
#include <boost/lambda/algorithm.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

using namespace std;
using namespace boost::lambda;

int main()
{
    map<string, int> m;
    map<string, int> m2;

    m["a"] = 1;
    m["b"] = 2;

    m2["c"] = 3;

    for_each(m.begin(), m.end(),
        bind(&map<string, int>::insert, &m2,
                 bind(&make_pair,
                     bind(&map<string, int>::value_type::first, _1),
                     bind(&map<string, int>::value_type::second, _1))));


    return EXIT_SUCCESS;
}

Unfortunately, the above code fails to compile and I have no idea
why it fails. I'm using g++ and the errors are as follows:

g++ map_test.cpp
map_test.cpp: In function 'int main()':
map_test.cpp:26: error: no matching function for call to 'bind(<unknown type>, const boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<2, boost::lambda::function_action<2, boost::lambda::detail::unspecified> >, boost::tuples::tuple<const std::basic_string<char, std::char_traits<char>, std::allocator<char> > std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>::* const, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> > >, const boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<2, boost::lambda::function_action<2, boost::lambda::detail::unspecified> >, boost::tuples::tuple<int std::pair<const std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>::* const, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> > >)'

Any idea on this?

Sincerely,
Minkoo Seo

Re: calling map::insert through bind.

by Phillip Hellewell-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 8/23/06, Minkoo Seo <minkoo.seo@...> wrote:
    for_each(m.begin(), m.end(),
        bind(&map<string, int>::insert, &m2,
                 bind(&make_pair,
                     bind(&map<string, int>::value_type::first, _1),
                     bind(&map<string, int>::value_type::second, _1))));

Unfortunately, the above code fails to compile and I have no idea
why it fails. I'm using g++ and the errors are as follows:

First off, just thought I would mention that for an example such as this, regular boost::bind would probably suffice. You don't need lambda.

Second of all, I don't know which insert function you are trying to call, but you should be able to write this code instead, which is much simpler:

   for_each(m.begin(), m.end(),
           bind(&map<string, int>::insert, m2, _1));

Finally, even that fails to compile!  I believe the problem is that since insert is an overloaded function, boost cannot figure out which one to call.  So you help it out by type-casting explicitly, like this:

   typedef pair<map<string, int>::iterator, bool> (map<string, int>::* InsertFunc)(const map<string, int>::value_type&);

   for_each(m.begin(), m.end(),
           bind(static_cast<InsertFunc>(&map<string, int>::insert), m2, _1));

It's ugly, but it works (actually, I tried with lambda and it still didn't work, but with regular boost::bind it does).

Now after going to ALL that work just so you can use for_each, don't you just want to forget it and use iterators?

   for( map<string, int>::const_iterator it = m.begin(); it != m.end(); ++it )
       m2.insert(*it);

Phillip Hellewell

_______________________________________________
Boost-users mailing list
Boost-users@...
http://lists.boost.org/mailman/listinfo.cgi/boost-users

Re: calling map::insert through bind.

by Felipe Magno de Almeida :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On 8/23/06, Phillip Hellewell <sshock@...> wrote:
>
> [snipped]

>
> Now after going to ALL that work just so you can use for_each, don't you
> just want to forget it and use iterators?
>
>    for( map<string, int>::const_iterator it = m.begin(); it != m.end(); ++it
> )
>        m2.insert(*it);

And after ALL this, you could write just:

std::map<std::string, int> m2(m1);

What am I missing? maps are copy-constructible!

>
> Phillip Hellewell

--
Felipe Magno de Almeida
_______________________________________________
Boost-users mailing list
Boost-users@...
http://lists.boost.org/mailman/listinfo.cgi/boost-users