Re: currying pointer to member functions
On Mar 6, 12:20 am, Jerry wrote:
I can make this work:
struct a
{
int b;
int c() {return b+1;}
int d(int x) {return b+x;}
};
int main()
{
a m = { 1 }, n = { 2 };
a *ps = &m;
int (a::*pf)() = &a::c;
std::cout << (ps->*pf)() << std::endl;
return 0;
}
And it runs the function and everything works. But what I want to
do is curry the function so that I can store (ps->*pf) and then
later execute it. So what is the type of &(ps->*pf) ?
The type of (ps->*pf) is int() but the C++ standard says that the only
thing you can do with it is to actually call the function via the
function call operator. That makes the expression &(ps->*pf) illegal.
I make a class:
template<class R, class O>
class ArrowStarVoidFunc
{
private:
R(O::*fptr)();
public:
ArrowStarVoidFunc(R(O::*f)()) : fptr(f) {}
R operator()(O* o) const { return (o->*fptr)(); }
};
template<class R, class O>
ArrowStarVoidFunc<R,O> operator->*(R(O::*f)())
{ return ArrowStarVoidFunc<R,O>(f); }
Which seems to work fine except it also executes the function.
This looks similar to what std::mem_fun already does.
What I
want to do is the following, but what goes where the ???? is:
template<class R, class O>
class ArrowStarVoidFunc
{
private:
R(O::*fptr)();
public:
ArrowStarVoidFunc(R(O::*f)()) : fptr(f) {}
???? operator()(O* o) const { return &(o->*fptr); }
};
Oh, and to make all this more interesting (i.e. complicated) I am
working with a compiler that is more than 10 years old and is only
compatible with C++98 - if I could a newer compiler I wouldn't be
asking this!
You can return a function object of a custom type:
template<typename R, class O>
class bound_mem_fun
{
public:
bound_mem_fun(R (O::*f)(), O* o)
: f(f), o(o) {}
R operator()() const
{ return (o->*f)(); }
private:
R (O::*f)();
O* o;
};
It stores the function pointer as well as the object pointer. The C+
+98 standard library is short on this kind of wrapper. It only
provides bind1st and bind2nd which take binary functors and return
unary functors.
In addition, C++11 offers a more general std::bind as well as lambda
expressions which would be of help here if you were not restricted to
C ++98. But maybe you can make use of Boost.Bind instead. It's kind of
the predecessor to std::bind:
O* o = ...;
R (O::*f) = ...;
boost::bind(f,o) ();
^^^^^^^^^^^^^^^^ ^^
yields nullary invokes
functor it
Cheers!
SG
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]