
On 7/29/05, Oleg Smolsky <oleg.smolsky@pacific-simulators.co.nz> 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