Jak podejrzewasz, podanie wskaźnika funkcji członka jest dopuszczalną praktyką.
Jeśli trzeba znać składnię, to jest:
int compute_(int a, int b, int (test::*f)(int,int))
{
int c=0;
// Some complex loops {
c += (this->*f)(a,b)
// }
return c;
}
Reprezentowanie funkcji składowych za pomocą liczb całkowitych i przełączanie wprowadza programista napowietrznych do przechowywania rzeczy aż do dnia, w którym lista dostępnych zmian operacyjnych. Więc nie chcesz tego, chyba że jest jakiś ważny powód w konkretnym przypadku.
Jedną z alternatyw jest, aby compute
nawet bardziej ogólnie - zamiast podejmowania funkcji składowej, napisać szablon funkcji, które ma każdy rodzaj wpłacone:
template <typename BinaryFunction>
int compute_(int a, int b, BinaryFunction f) {
// body as before but `f(a,b)` instead of `(this->*f)(a,b)`
}
Ten bardziej ogólny szablon jest super, jeśli ktoś chce korzystać to z pewnym operatorem własnego wynalazku, który nie jest funkcją członkowską z test
. Jest trudniejsze w użyciu w przypadku funkcji członka, ponieważ ktoś musi przechwycić this
. Można to zrobić na kilka sposobów - lambda C++ 11, boost::bind
lub napisanie londyńskiej gryfowej. Na przykład:
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));
}
Definiowanie bind_this
jest trochę bólu: to jak std::bind1st
wyjątkiem tego, że chcielibyśmy pracować z 3-arg funktor natomiast bind1st
zajmuje tylko binarny funktor. boost::bind
i std::bind
w C++ 11, są bardziej elastyczne i będą obsługiwać dodatkowe argumenty.Poniższa zrobi w tym przypadku, ale nie działa w ogóle powiązać funkcje składowe 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) {}
};
w C++ 11 można po prostu użyć 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) });
}
Masz znacznik 'member-function-indexers'. Czy to nie jest dobre miejsce na rozpoczęcie? – chris
@ Chris chyba nie ma pewności co do składni? – RedX
Jeśli metody, które chcesz przekazać, są takie same, jak w twojej próbce, wystarczą proste funkcje (statyczne) i zwykłe wskaźniki funkcji. – Mat