From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2003-06-05 12:32:39


In this comp.lang.c++.moderated thread
(http://www.google.com/groups?selm=2045294.t6ppZr3Erj%40technoboredom.net),
there was the following request:

--- Start quote ---

For some reason (I want to pass function pointers to certain libraries) I'd
like to convert a member function into a real function pointer. gcc has an
extension which can do that, but for portability I came up with this
solution:

[...]

// use it
class A
{
public:
  int a_member(int k)
  {
    return k*k;
  }
};

int main()
{
  int (*fn)(A*, int)=bmfhelper(&A::a_member).getfun<&A::a_member>();
  A a;
  int r=fn(&a, 3); // sets r to 9
}

The duplication of &A::a_member as a function *and* a template parameter
looks awkward to me, but I can't figure out a way to avoid this. I somehow
need that bmfhelper function call to make the template value parameter
possible. Has anybody a better idea?

--- End quote ---

I immediately thought of boost::function, and suggested that. Then you could
write it like this:

int main()
{
  boost::function<int (A*, int)> fn=&A::a_member;

  // The rest the same

  A a;
  int r=fn(&a, 3); // sets r to 9
}

However, it turned out that this couldn't be used for OP, as a real function
pointer, not a function object, was needed. That's understandable, if you
want to pass it to libraries that take a function pointer (for example
callbacks).

After some experimentation, for Hiram Berry and I, in the thread, we finally
arrived at a way it could be done, which may be used in practically the same
way as boost::function. It can be used like this:

int main()
{
  function_ptr<int (A*, int), &A::a_member> fn;

  // The rest the same

  A a;
  int r=fn(&a, 3); // sets r to 9
}

It creates a function object, but it has an implicit conversion to a
function pointer of the specified type, which calls the member function,
using the given object and any parameters.

Could there be any interest in this? For cases where a function pointer,
rather than function object, is required.

I've attached a version that has been tested on Intel C++ 7.1 and g++ 3.2,
and it includes a test.

The current version handles from 0 to 2 parameters, but can be extended
arbitrarily. It should probably handle the same number of arguments as
boost::function. Alternatively, this capability might be incorporated into
boost::function, if possible.

For a comparison between function objects and function pointers, see
(http://www.boost.org/doc/html/function.misc.html).

Since the member function is called from the function, it still requires two
calls through function pointers, like boost::function. However, the pointer
itself only takes up the size of one pointer, and it may be used with
libraries requiring function pointers, as mentioned.

Feedback is welcome.

Regards,

Terje