Boost logo

Boost Users :

From: Stuart Dootson (stuart.dootson_at_[hidden])
Date: 2005-07-28 18:30:39


On 7/29/05, Oleg Smolsky <oleg.smolsky_at_[hidden]> wrote:
> Hello Dave, Stuart,
>
> Dave Slutzkin wrote on 28/07/2005 at 6:21 p.m.:
> >> std::for_each(v.begin(), v.end(),
> >> boost::bind(&Handler::Test1, _1, a));
> > This creates a functor with one argument, _1, which calls
> > Handler::Test1 with _1 as this and a as argument 1 of Test1.
> Right.
>
> > I think what you want is:
> > std::for_each(v.begin(), v.end(),
> > boost::bind(&Handler::Test2, _1, a, b));
> > To create a functor with one argument, _1, which calls
> > Handler::Test2 with _1 as this, a as argument 1 of Test2 and b as
> > argument 2 of Test2.
> Right, that's exactly what I needed. Thanks.
>
> >> // This doesn't compile
> >> //std::for_each(v.begin(), v.end(),
> >> // boost::bind(&Handler::Test2, _1, _2, a, b));
> > This creates a functor with two arguments, _1 and _2, which calls
> > Handler::Test2 with _1 as this, _2 as argument 1 of Test2, a as argument
> > 2 of Test2 and b as argument 3 of Test2. But Test2 only has two
> > arguments, and for_each only takes a functor with one argument.
> This is very confusing.... Let me paraphrase your explanation: I was
> trying to feed an extra argument to bind, which takes parameters in
> this fashion: boost::bind(function, this, arg1, arg2, arg3, etc)
>
> Right?
>
> If yes, what's the exact meaning of _1, _2 placeholders? Also, how
> does that mash with functions vs methods?
>
> Best regards,
> Oleg.
>

When using boost.bind, a method is effectively treated as a function
with an unstated first parameter (i.e. this). So, if we have the
following declarations:

struct A
{
   void AMethod(std::string const& a, std::string const& b);
};

void AFunction(A object, std::string const& a, std::string const& b);

std::vector<A> vecOfA;
std::string s1, s2;

Then the following are both correct:

std::for_each(vecOfA.begin(), vecOfA.end(), boost::bind(&A::AMethod,
_1, s1, s2));
std::for_each(vecOfA.begin(), vecOfA.end(), boost::bind(&AFunction,
_1, s1, s2));

In both cases, boost::bind creates a function object that has an
operator() with a signature like that shown below:

struct <some_type_dependent_on_boost_bind_implementation>
{
   void operator()(A object);
};

The for_each algorithm supplies an object of type A (from vecOfA) as a
parameter to the operator(). The implementation of the operator()
takes this parameter and the two strings supplied in the boost::bind
function call and calls the function you bound, putting the parameter
supplied by for_each wherever _1 was used in the bind function call.

Think about if you contructed a function object by hand:

struct FuncObj
{
   FuncObj(std::string const& str1, std::string const& str2) :
str1_(str1), str2_(str2) {}

   void operator()(A object) { AFunction(object, str1_, str2_); }

   std::string str1_;
   std::string str2_;
};

std::for_each(vecOfA.begin(), vecOfA.end(), FuncObj(s1, s2));

You can see that the string arguments are supplied when you construct
the function object, while the A parameter is passed into the function
object when it is called, and passed through to the intended function.

HTH
Stuart Dootson


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net