Topic: Extension to the <functional> header.


Author: ".hpp" <hp.peti@gmail.com>
Date: Mon, 14 Nov 2005 16:52:26 CST
Raw View
Hi everybody!

I recently started to change the virtual function call mechanism with
function objects, because they give more flexibility and speed.
At some point I realized that something is really missing from the
<functional> library that can be used in many situations: a class
member function adapter class.
I knew that there were the mem_fun_t class family, but they call their
first argument's member, and I wished to call any other classes' any
member.

So I came up with the idea of an "any class member" function adapter
with 0, 1 and 2 parameters.

I guess that, altough its functionality can be somewhat achieved
through binder1st<mem_fun_t>,  it's not a bad idea to append to the
standard library. It is already formally compatible. :)

Give me some feedback, please.

Hanos-Puskai Peter

-----------------------------------------------------------------
Sample code:

#include <iostream>
#include <algorithm>

// this is my "functional extension", see code fragment below
#include <func_ext.hpp>

using namespace std;
using namespace std;
class A
{
 int z;
public:
 A():z(0){}

 int DoSomething(int x){cout<<(z+=x)<<endl;return z;}
 int DoSomethingElse(int x)const{cout<<z+x<<endl;return z;}
};

void main()
{
 int z[]={1,2,3,4,5,6,7,8,9,0};
 A a;
 // call a.DoSomething on each z
 for_each(z,z+9,class_ptr_fun1<int,A,int>(&a,A::DoSomething));
 // call a.DoSomethingElse on each z
 for_each(z,z+9,const_class_ptr_fun1<int,A,int>(&a,A::DoSomethingElse));
}

Output:
1
3
6
10
15
21
28
36
45
46
47
48
49
50
51
52
53
54

And some fragment from the header <func_ext.hpp>

// TEMPLATE CLASS class_ptr_fun1_t
template<class _R,class _Ty,class _A>
class class_ptr_fun1_t:
 public std::unary_function<_A,_R>
{
 _Ty *T;_R (_Ty::*Ptr)(_A);
public:
 class_ptr_fun1_t(_Ty *T,_R (_Ty::*Ptr)(_A)):T(T),Ptr(Ptr){}
 _R operator()(_A A){return (T->*Ptr)(A);}
};
// TEMPLATE FUNCTION class_ptr_fun1
template<class _R,class _Ty,class _A>
inline class_ptr_fun1_t<_R,_Ty,_A> class_ptr_fun1(_Ty *T,_R
(_Ty::*Ptr)(_A))
{
 return class_ptr_fun1_t<_R,_Ty,_A>(T,Ptr);
}

// TEMPLATE CLASS const_class_ptr_fun1_t
template<class _R,class _Ty,class _A>
class const_class_ptr_fun1_t:
 public std::unary_function<_A,_R>
{
 const _Ty *T;_R (_Ty::*Ptr)(_A) const;
public:
 const_class_ptr_fun1_t(const _Ty *T,_R (_Ty::*Ptr)(_A)
const):T(T),Ptr(Ptr){}
 _R operator()(_A A)const{return (T->*Ptr)(A);}
};

// TEMPLATE FUNCTION const_class_ptr_fun1
template<class _R,class _Ty,class _A>
inline const_class_ptr_fun1_t<_R,_Ty,_A> const_class_ptr_fun1(const _Ty
*T,_R (_Ty::*Ptr)(_A) const)
{
 return const_class_ptr_fun1_t<_R,_Ty,_A>(T,Ptr);
}

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Tue, 15 Nov 2005 17:11:05 GMT
Raw View
.hpp wrote:
>
> I guess that, altough its functionality can be somewhat achieved
> through binder1st<mem_fun_t>,  it's not a bad idea to append to the
> standard library. It is already formally compatible. :)
>
> Give me some feedback, please.
>

What you did is really interesting. So interesting that something like
your proposal, but much more flexible and complete, has already been
approved for introduction in the next revision of the C++ standard
library (the so-called TR1). See for yourself:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf
(chapter 3, function objects).

You may want to have a look at an existing implementation of the new
generalized binders in the Boost libraries
(http://www.boost.org/libs/libraries.htm#Function-objects).

HTH,

Ganesh

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Martin" <wpcmame@hotmail.com>
Date: Tue, 15 Nov 2005 11:16:21 CST
Raw View
>// call a.DoSomething on each z
>for_each(z,z+9,class_ptr_fun1<int,A,int>(&a,A::DoSomething));

for_each(z, z+9, boost::bind(&A::DoSomething, &a,  _1));

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Ferdi.Smit@cwi.nl (Ferdi Smit)
Date: Tue, 15 Nov 2005 17:16:40 GMT
Raw View
.hpp wrote:
> Hi everybody!
>
> I recently started to change the virtual function call mechanism with
> function objects, because they give more flexibility and speed.
> At some point I realized that something is really missing from the
> <functional> library that can be used in many situations: a class
> member function adapter class.
> I knew that there were the mem_fun_t class family, but they call their
> first argument's member, and I wished to call any other classes' any
> member.
>
> So I came up with the idea of an "any class member" function adapter
> with 0, 1 and 2 parameters.

A noble idea :) Although Boost.Bind already provides this...see
mem_fn.hpp. Afiak some of the boost libs have a good chance of being
added to the next C++ standard, so you might get lucky.

--
Regards,

Ferdi Smit (M.Sc.)
Email: Ferdi.Smit@cwi.nl
Room: C0.07  Phone: 4229
INS3 Visualization and 3D Interfaces
CWI Amsterdam, The Netherlands

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Tom Widmer" <tom_usenet@hotmail.com>
Date: Tue, 15 Nov 2005 11:16:35 CST
Raw View
.hpp wrote:
> Hi everybody!
>
> I recently started to change the virtual function call mechanism with
> function objects, because they give more flexibility and speed.
> At some point I realized that something is really missing from the
> <functional> library that can be used in many situations: a class
> member function adapter class.
> I knew that there were the mem_fun_t class family, but they call their
> first argument's member, and I wished to call any other classes' any
> member.

You mean you wanted to make a functor which took an argument other than
the class to call the member function of? The binder facilities give
you this. e.g.

for_each(z,z+9,bind1st(mem_fun(&A::DoSomething), &a));
for_each(z,z+9,bind1st(mem_fun(&A::DoSomethingElse), &a));

In addition, TR1 is adding a new library facility, bind. With that you:

for_each(z,z+9,bind(&A::DoSomething, &a, _1));

See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf

Tom

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "=?iso-8859-1?q?Hanos-Puskai_P=E9ter?=" <hp.peti@gmail.com>
Date: Wed, 16 Nov 2005 13:23:29 CST
Raw View
Thanks for your comments. I consider now this topic closed.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]