using bind with find_if
Hello,
I am currently using find_if with bind2nd to perform a search on a vector.
My current code looks like this:
struct OverrideMatches : public std::binary_function
I am currently using find_if with bind2nd to perform a search on a vector. My current code looks like this:
struct OverrideMatches : public std::binary_function
{ bool operator()( const TItemOverride& OverrideSource, TItemOverride OverrideTarget ) const { return OverrideSource.ChildAssyItemRecNo == OverrideTarget.ChildAssyItemRecNo && OverrideSource.LinkItemRecNo == OverrideTarget.LinkItemRecNo; } }; TItemOverrideGateway::Container_t::iterator where = std::find_if( FOverridesContainer.begin(), FOverridesContainer.end(), std::bind2nd( OverrideMatches(), TItemOverride( "", 0, "", 0, ChildItemRecNo, LinkItemRecNo ) ) );
Excuse my ignorance, but if you just want to find elements equal to some specific element, why don't you use simply std::find() -- without binds etc.?
----- Original Message -----
From: "Igor R"
I am currently using find_if with bind2nd to perform a search on a vector. My current code looks like this:
struct OverrideMatches : public std::binary_function
{ bool operator()( const TItemOverride& OverrideSource, TItemOverride OverrideTarget ) const { return OverrideSource.ChildAssyItemRecNo == OverrideTarget.ChildAssyItemRecNo && OverrideSource.LinkItemRecNo == OverrideTarget.LinkItemRecNo; } }; TItemOverrideGateway::Container_t::iterator where = std::find_if( FOverridesContainer.begin(), FOverridesContainer.end(), std::bind2nd( OverrideMatches(), TItemOverride( "", 0, "", 0, ChildItemRecNo, LinkItemRecNo ) ) );
Excuse my ignorance, but if you just want to find elements equal to some specific element, why don't you use simply std::find() -- without binds etc.?
I don't want to find elements equal to a specific element. I want to find an element that meets specific criteria -- that is, find the element for which two of its data members have specific values. If I already had all the criteria for the element, I wouldn't need to find it in the first place! - Dennis
I don't want to find elements equal to a specific element. I want to find an element that meets specific criteria -- that is, find the element for which two of its data members have specific values. If I already had all the criteria for the element, I wouldn't need to find it in the first place!
I see... You can do something like this: std::find_if(FOverridesContainer.begin(), FOverridesContainer.end(), boost::bind(OverrideMatches(), _1, ChildItemRecNo, LinkItemRecNo)); or with Boost.Range algorithm: boost::find_if(FOverridesContainer, boost::bind(OverrideMatches(), _1, ChildItemRecNo, LinkItemRecNo));
"Igor R"
I see... You can do something like this:
std::find_if(FOverridesContainer.begin(), FOverridesContainer.end(), boost::bind(OverrideMatches(), _1, ChildItemRecNo, LinkItemRecNo));
Oh, of course! Now that I see it, it makes perfect sense. For some reason, I was thinking that I needed placeholders for all values being passed to the functor, when all I really needed was the placeholder for the element in the vector because I have the actual values for the 2nd and 3 parameters. I just have to add: typedef bool result_type; to my functor, or call boost::bind<bool>. Thanks! - Dennis
I just have to add:
typedef bool result_type;
to my functor, or call boost::bind<bool>.
Or just define a simple function instead of the functor (which is stateless anyway). By the way, if you've got a lot of tasks where you extract elements according to some criteria, it's worth taking a look at Boost.MultiIndex - it's quite powerful tool for both trivial and complicated cases.
"Igor R"
I just have to add:
typedef bool result_type;
to my functor, or call boost::bind<bool>.
Or just define a simple function instead of the functor (which is stateless anyway).
Thanks for the suggestion. However, this:
bool OverrideMatches(
const TItemOverride &OverrideSource,
const RecNo_t ChildItemRecNo, <-- note: these are const
const RecNo_t LinkItemRecNo )
{
return
OverrideSource.ChildAssyItemRecNo == ChildItemRecNo &&
OverrideSource.LinkItemRecNo == LinkItemRecNo;
}
const RecNo_t ChildItemRecNo = 123; <-- note: these are const too
const RecNo_t LinkItemRecNo = 456;
std::find_if(
FOverridesContainer.begin(),
FOverridesContainer.end(),
boost::bind(OverrideMatches, _1, ChildItemRecNo, LinkItemRecNo) );
results in an error:
[C++ Error] bind_cc.hpp(50, 4): E2034 Cannot convert
'_bi::bind_t
Thanks for the suggestion. However, this:
bool OverrideMatches( const TItemOverride &OverrideSource, const RecNo_t ChildItemRecNo, <-- note: these are const const RecNo_t LinkItemRecNo ) { return OverrideSource.ChildAssyItemRecNo == ChildItemRecNo && OverrideSource.LinkItemRecNo == LinkItemRecNo; }
const RecNo_t ChildItemRecNo = 123; <-- note: these are const too const RecNo_t LinkItemRecNo = 456;
std::find_if( FOverridesContainer.begin(), FOverridesContainer.end(), boost::bind(OverrideMatches, _1, ChildItemRecNo, LinkItemRecNo) );
results in an error:
[C++ Error] bind_cc.hpp(50, 4): E2034 Cannot convert '_bi::bind_t
(*)(),_bi::value<const unsigned int>,_bi::value<const unsigned int> > >' to '_bi::bind_t (*)(),_bi::value<const unsigned int>,_bi::value<const unsigned int> > >'
What version do you use? I 1.45 the following compiles well:
#include <vector>
#include <algorithm>
#include
Ah, forgot to mention that I test it with MSVC10. And IIRC, I saw recently on this list some issue, which is similar to yours, and if I remember correctly it was related to a bug in an older version of gcc.
Here it is: http://thread.gmane.org/gmane.comp.lib.boost.user/65634/focus=65639
On 10 March 2011 08:30, Dennis Jones
I am using Boost 1.33.1 with Borland C++Builder 5 (an old compiler, to be sure).
If you can upgrade to Boost 1.36 or later, the following should work (note: untested): bind(&TItemOverride::ChildAssyItemRecNo, _1) == ChildItemRecNo && bind(&TItemOverride::LinkItemRecNo, _1) == LinkItemRecNo and you don't even need your OverrideMatches class. Alternatively, that should also work using the lambda library (boost::lambda::bind instead of boost::bind), even under Boost 1.33.1. -- Nevin ":-)" Liber mailto:nevin@eviloverlord.com (847) 691-1404
"Nevin Liber"
participants (3)
-
Dennis Jones
-
Igor R
-
Nevin Liber