RE: [Boost-Users] Getting the hang of Boost::Bind
-----Original Message----- From: Douglas Gregor [mailto:gregod@cs.rpi.edu] Sent: Friday, August 09, 2002 3:32 PM To: Boost-Users@yahoogroups.com Subject: Re: [Boost-Users] Getting the hang of Boost::Bind
On Friday 09 August 2002 06:08 pm, Tom Matelich wrote:
I have a vector of
class Landmark { public: std::string const& getName() const; ... };
I want to do a find_if for a name that I have.
something like std::find_if(begin, end, boost::bind(std::equalstd::string(???, name_to_find)));
What do I put for the ??? ?
I presume that [begin, end) is an iterator sequence of Landmark instances? Then ??? = boost::bind(&Landmark::getName, _1), meaning that the first parameter to std::equalstd::string::operator() is a call to Landmark::getName where the object parameter (this) is the first argument (_1) to the bind function object.
Thanks for the quick reply. That's what I thought. To make things more
concrete...
std::vector<Landmark> v;
...
std::vector<Landmark>::const_iterator iter =
std::find_if(v.begin(), v.end(),
boost::bind(std::equalstd::string,
boost::bind(ZLandmark::Landmark::getName, _1),
name_to_find));
Is what I think you're telling me. Perhaps I should mention now that I am
using VC6. Compiling the above line I get many errors, here are the first
three:
inspdoc.cpp(453) : error C2780: 'class boost::_bi::bind_t
__cdecl boost::bind(R (__thiscall T::*)(B1,B2,B3,B4,B5,B6,B7, B8) const,A1,A2,A3,A4,A5,A6,A7,A8,A9)' : expects 10 arguments - 3 provided c:\dev\opt\include\boost/bind/bind_mf_cc.hpp(223) : see declaration of 'bind' inspdoc.cpp(453) : error C2780: 'class boost::_bi::bind_t
,class boost::_bi::list9 __cdecl boost::bind(R (__thiscall T::*)(B1,B2,B3,B4,B5,B6,B7,B 8),A1,A2,A3,A4,A5,A6,A7,A8,A9)' : expects 10 arguments - 3 provided c:\dev\opt\include\boost/bind/bind_mf_cc.hpp(212) : see declaration of 'bind'
Oh, and I guess that should be std::equal_to, right? Didn't work either though. Thanks, Tom PS Unfortunately, I have to run. I'll be looking at this again this weekend though. ----------------------------------------------------------------------- DISCLAIMER: Information contained in this message and/or attachment(s) may contain confidential information of Zetec, Inc. If you have received this transmission in error, please notify the sender by return email. -----------------------------------------------------------------------
On Friday 09 August 2002 06:40 pm, Tom Matelich wrote:
std::vector<Landmark> v; ... std::vector<Landmark>::const_iterator iter = std::find_if(v.begin(), v.end(), boost::bind(std::equalstd::string, boost::bind(ZLandmark::Landmark::getName, _1), name_to_find));
Oh, and I guess that should be std::equal_to, right? Didn't work either though.
I'm not sure what the error message is, but to clean up the errors I see: std::vector<Landmark>::const_iterator iter = std::find_if(v.begin(), v.end(), boost::bind<bool>(std::equal_tostd::string(), boost::bind(&Landmark::getName, _1), name_to_find)); Mostly just syntactic cleanups, but the boost::bind<bool> part is important. It's required because of some MSVC quirks, and basically tells bind that the return type for the function object will be 'bool'. Otherwise, bind would try to figure out the return type on its own, and I think that requires partial specialization (not supported on current versions of MSVC). Doug
std::vector<Landmark>::const_iterator iter = std::find_if(v.begin(), v.end(), boost::bind<bool>(std::equal_tostd::string(), boost::bind(&Landmark::getName, _1), name_to_find));
I've not started using boost::bind yet, but I've been meaning to for some time, and I have read up on it, but one thing confuses me. Am I right in thinking that boost::bind will automatically detect whether the function call should be a->f(), a.f() or f(a)? If so, how does it handle the (admittedly very pathological) situation like this: struct B; struct A { bool f(); B* operator->(); }; struct B { bool f(); }; bool f(const A& a); std::vector<A> v; std::vector<A>::const_iterator iter = std::find_if(v.begin(), v.end(), boost::bind(&A::f, _1)); Presumably it does the right thing and calls A::f, but how does it do that? Cheers sam
On Monday 12 August 2002 05:10 am, Sam Partington wrote:
Am I right in thinking that boost::bind will automatically detect whether the function call should be a->f(), a.f() or f(a)?
Bind deals with either function objects or pointers to member functions, so the forms are: (a.*f)() and (a->*f)() for pointers to member functions, or f(a) for function objects.
bool f(const A& a);
std::vector<A> v;
std::vector<A>::const_iterator iter = std::find_if(v.begin(), v.end(), boost::bind(&A::f, _1));
Presumably it does the right thing and calls A::f, but how does it do that?
When bind has a pointer-to-member function, it has the return type and the argument types. Most importantly, it has the type of the object it will be called with: 'A' The trick is this: when you call the bind object as f(x), bind is going to try to determine if 'x' is an A or is derived from A. If so, it can proceed with the call as (x.*f)(). Otherwise, bind assumes that 'x' is some form of pointer and uses a 'get_pointer' facility to extract a raw pointer to call via (get_pointer(x)->*f)(). [All this logic is actually part of mem_fn, not bind; bind just wraps mem_fn in these cases] Doug
participants (3)
-
Douglas Gregor
-
Sam Partington
-
Tom Matelich