From: fleebis on
I've wondered if I'm missing something when I do searches in stl
collections, to find an element that has a member that has a certain
value. I don't want to have to write any special function object or
accessor function, there should be a function adaptor that takes a
member pointer (not a member function pointer.)

I tried to write one since I can't find this in the stl:

template<typename T, typename T2, T2 T::*ptr, T2 value>
class member_equal_to
{
public:
bool operator()(const T& ref)
{
return (ref.*ptr == value);
}
};

Now I can search for any struct member:

struct abc
{
int x;
int y;
};

int main()
{
list<abc> mylist;

...

mylist::iterator iter =
find_if( mylist.begin(), mylist.end(),
member_equal_to<abc,int, &abc::y, 4>());
// look for item with y == 4


...
}

Is there a "right" way to do this?

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: marcin.sfider on
On Jun 12, 12:44 am, fleebis <mrus...(a)hotmail.com> wrote:
> I've wondered if I'm missing something when I do searches in stl
> collections, to find an element that has a member that has a certain
> value. I don't want to have to write any special function object or
> accessor function, there should be a function adaptor that takes a
> member pointer (not a member function pointer.)
>
> I tried to write one since I can't find this in the stl:
>
> template<typename T, typename T2, T2 T::*ptr, T2 value>
> class member_equal_to
> {
> public:
> bool operator()(const T& ref)
> {
> return (ref.*ptr == value);
> }
>
> };
>
> Now I can search for any struct member:
>
> struct abc
> {
> int x;
> int y;
>
> };
>
> int main()
> {
> list<abc> mylist;
>
> ...
>
> mylist::iterator iter =
> find_if( mylist.begin(), mylist.end(),
> member_equal_to<abc,int, &abc::y, 4>());
> // look for item with y == 4
>
> ...
>
> }
>
> Is there a "right" way to do this?

First I thought that use of boost::bind (std::bind in C++1x?)
would be perfect for this. Then I saw there are no accessors defined.
But I gave it a try and it worked :)

std::list<abc>::iterator iter = std::find_if(mylist.begin(),
mylist.end(),
boost::bind(&abc::x, _1) == 4);

Don't know if this is the "right" way, but that's the way I would do
it.

Cheers
Sfider


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Daniel Krügler on
On 12 Jun., 18:24, "marcin.sfi...(a)gmail.com" <marcin.sfi...(a)gmail.com>
wrote:
> On Jun 12, 12:44 am, fleebis <mrus...(a)hotmail.com> wrote:
>
> > I've wondered if I'm missing something when I do searches in stl
> > collections, to find an element that has a member that has a certain
> > value. I don't want to have to write any special function object or
> > accessor function, there should be a function adaptor that takes a
> > member pointer (not a member function pointer.)
>
> > I tried to write one since I can't find this in the stl:
>
> > template<typename T, typename T2, T2 T::*ptr, T2 value>
> > class member_equal_to
> > {
> > public:
> > bool operator()(const T& ref)
> > {
> > return (ref.*ptr == value);
> > }
> > };
>
> > Now I can search for any struct member:
>
> > struct abc
> > {
> > int x;
> > int y;
> > };
>
> > int main()
> > {
> > list<abc> mylist;
> > ...
> > mylist::iterator iter =
> > find_if( mylist.begin(), mylist.end(),
> > member_equal_to<abc,int, &abc::y, 4>());
> > // look for item with y == 4
> > ...
> > }
> > Is there a "right" way to do this?
>
> First I thought that use of boost::bind (std::bind in C++1x?)
> would be perfect for this. Then I saw there are no accessors defined.
> But I gave it a try and it worked :)
>
> std::list<abc>::iterator iter = std::find_if(mylist.begin(),
> mylist.end(),
> boost::bind(&abc::x, _1) == 4);
>
> Don't know if this is the "right" way, but that's the way I would do
> it.

It's maybe noteworthy to mention that as of the current
FCD for C++0x this functionality will be standardized.
First, via std::mem_fn any pointer to member can be wrapped
as a function object and second, std::bind is capable to
bind any /callable type/, which is either a function
object or a pointer to member.

HTH & Greetings from Bremen,

Daniel Kr�gler


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]