Prev: Templates rejected on non-dependent parameters before deduction in C++0X?
Next: Templates rejected on non-dependent parameters before deduction in C++0X?
From: fleebis on 11 Jun 2010 07:44 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 12 Jun 2010 01:24 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 12 Jun 2010 19:09
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! ] |