Como sospechabas, pasar un puntero de función miembro es una práctica aceptable.
Si necesita conocer la sintaxis, que es:
int compute_(int a, int b, int (test::*f)(int,int))
{
int c=0;
// Some complex loops {
c += (this->*f)(a,b)
// }
return c;
}
En representación de las funciones miembro utilizando números enteros, y conmutación, supone cargas programador para mantener las cosas al día cuando la lista de cambios de operaciones disponibles. Entonces no quieres eso a menos que haya alguna razón importante en un caso particular.
Una alternativa es hacer compute
incluso más general - en lugar de tomar una función miembro, escribir una plantilla de función que toma cualquier tipo exigible:
template <typename BinaryFunction>
int compute_(int a, int b, BinaryFunction f) {
// body as before but `f(a,b)` instead of `(this->*f)(a,b)`
}
Esta plantilla más general es grande si alguien quiere usar con un operador de su propia invención, que no es una función miembro de test
. Sin embargo, es más difícil de usar en el caso de la función de miembro porque alguien necesita capturar this
. Hay algunas formas de hacerlo: un C++ 11 lambda, boost::bind
, o escribir un functor a mano. Por ejemplo:
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));
}
Definición bind_this
es un poco de dolor: es como std::bind1st
excepto que nos gustaría trabajar con un 3-arg funtor mientras que bind1st
sólo toma un funtor binario. boost::bind
y std::bind
en C++ 11, son más flexibles y manejarán los argumentos adicionales.A continuación se va a hacer por este caso, pero no funciona en general para unir las funciones miembro 2-arg:
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) {}
};
En C++ 11 sólo se puede utilizar una 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) });
}
Tiene una etiqueta 'member-function-pointers'. ¿No es ese un buen lugar para comenzar? – chris
@chris supongo que está confundido acerca de la sintaxis? – RedX
Si los métodos que desea aprobar son los mismos que en su muestra, las funciones simples (estáticas) y los punteros de funciones normales son suficientes. – Mat