Reputation: 357
I've trying to avoid C-style function pointers in favor of std::function objects, but I'm having problems calling member functions while inheriting.
I have a method that receives a std::function:
class A
{
public:
void testCallbackA();
// this is unrelated, but I need some features from the superclass
void goingToNeedThisWhenCallingTestCallbackA(int someParams);
};
void method(std::function<void(A*)> callback);
method(&A::testCallbackA); // this works fine
All good by now, But when I want to use A subclasses with method I need to cast the function pointer:
class B : public A
{
public:
void testCallbackB() { }
};
method(&B::testCallbackB); // this fails
std::function<void(A*)> call = &B::testCallbackB; // this fails
std::function<void(B*)> call = &B::testCallbackB; // this works
If I want to be able to call method(&B::testCallbackB) I need to typedef a function pointer and cast it this way:
typedef void (A::*Callback)();
std::function<void(A*)> call = (Callback)&B::testCallbackB; // this works
Can I avoid this typedef? Can I avoid the cast? I've tried looking into std::bind with no luck.
Any ideas?
Upvotes: 0
Views: 553
Reputation:
If I understand your problem well, then I suggest you to make testCallbackA in class A virtual, and then simply use &A::testCallbackA when calling method.
Dynamic method dispatch will take care of calling the method of the actual class, and you do not have to circumvent type safety by hand.
Upvotes: 1
Reputation: 42564
This conversion should fail, because it's a bad idea. std::function<void(A*)>
is callable with any A*
, regardless of whether or not the actual object pointed to is a B
. The result of calling a B
member function on an A
that is not a B
is undefined behavior.
Upvotes: 5
Reputation: 409356
You might need std::bind
, like in
B b;
method(std::bind(&B::testCallbackB, b));
Upvotes: 4