As you suspected, passing a member function pointer is acceptable practice.
If you need to know the syntax, this is:
int compute_(int a, int b, int (test::*f)(int,int)) { int c=0;
Representing member functions using integers and switching introduces the overhead of the programmer to update the list of available operations. Therefore, you do not want this, if in a particular case there is no important reason.
One option is to make compute even more general - instead of accepting a member function, write a function template that accepts any type being called:
template <typename BinaryFunction> int compute_(int a, int b, BinaryFunction f) {
This more general pattern is great if someone wants to use it with some kind of operator of their invention, which is not a test member function. However, it is harder to use in the case of a member function, because someone needs to capture this . There are several ways to do this - C ++ 11 lambda, boost::bind or write a long handwriter. For example:
template <typename BinaryFunction> int compute_(int a, int b, BinaryFunction f) { // body as before with `f(a,b)` } int compute_(int a, int b, int (test::*f)(int,int)) { return compute_(a, b, bind_this(f, this)); }
The definition of bind_this bit painful: it likes std::bind1st , except that we would like to work with a 3-arg functor, whereas bind1st only accepts a binary functor. boost::bind and std::bind in C ++ 11 are more flexible and will handle extra arguments. For this case, the following will be executed, but does not work at all for linking 2-arg member functions:
struct bind_this { int (test::*f)(int,int); test *t; int operator(int a, int b) const { return (t->*f)(a,b); } bind_this(int (test::*f)(int,int), test *t) : f(f), t(t) {} };
In C ++ 11, you can just use lambda:
int compute_(int a, int b, int (test::*f)(int,int)) { return compute_(a, b, [=](int c, int d){ return (this->*f)(c,d) }); }