Reputation: 2119
I'm wondering if there's a way in standard C++ (it seems this is not supported but perhaps I didn't look hard) to declare a pointer to any class' member function with the same signature. For example, X and Y have echoX and echoY methods with the same signature
class X{
int val;
public:
int echoX(int v) {
val = v;
return v; }
int getValue() const { return val; }
};
class Y{
int val;
public:
int echoY(int v) {
val = v;
return v;
}
int getValue() const { return val; }
};
Some C++ implementations allow this functionality via extensions (e.g VCL makes use of the __closure
keyword).
typedef int (__closure *IntFunPtr)(int);
Now, it's trivial to write a function that is able to call either X::echoX
or Y::echoY
void CallObjectMethod(IntFunPtr fPtr, int val){
fPtr(val);//this can call any member method that accepts an int and returns an int
}
X x, x1;
CallObjectMethod(&x.echoX,4);
CallObjectMethod(&x1.echoX,20);
Y y, y1;
CallObjectMethod(&y.echoY,10);
CallObjectMethod(&y1.echoY,15);
This functionality can be useful for implementing event handlers, among other things.
Thank you
Upvotes: 3
Views: 3223
Reputation: 1894
You could create a generic templated function which accepts the signature you are interested in, pass in the instance of the object and the pointer to the member function. For example:
template<typename T>
void CallObjectMethod(int(T::*func)(int), T& obj, int val)
{
cout << (obj.*func)(val);
}
Now to call it like you mentioned in your example:
X x, x1;
CallObjectMethod(&X::echoX, x, 10);
CallObjectMethod(&X::echoX, x1, 20);
For object Y you could do something like:
Y y, y1;
CallObjectMethod(&Y::echoY, y, 10);
CallObjectMethod(&Y::echoY, y1, 20);
Upvotes: 3
Reputation: 668
"For example, X and Y have echoX and echoY methods with the same signature"
Afaik they dont have the same signature, they have an implicit first argument to the class instance. Usually you would choose an std::function
to get rid of the first argument.
#include <functional>
class X { public: int echoX(int v) {return v; } };
class Y { public: int echoY(int v) {return v; } };
typedef std::function<int(int)> IntFunction;
int echo(IntFunction func, int v)
{
return func(v);
}
int main()
{
int v = 5;
X x;
Y y;
int a = echo(std::bind(&X::echoX, x, std::placeholders::_1), v);
int b = echo(std::bind(&Y::echoY, y, std::placeholders::_1), v);
}
Upvotes: 6