Reputation: 163
it might be strange what i'm trying to see and i will try to clarify as much as possible. I'm using gcc 4.8 on ubuntu 14.04 and C++11.
What i want trying to do is:
give a pointer to that method of class B to a method of parentclass A as argument
class A{
typedef void(A::*METHOD);
void executeMethod(METHOD arg){};
}
class B : A{
void sampleMethod(){};
void childMethod(){
this->executeMethod(&B::sampleMethod); //<== error
}
}
However this brings me the following error in codeblocks:
error: no matching function to call for 'B::executeMethod(void B::*)'
Is there any way around this? Is there anything else i need to do to make it clear to you, what i'm trying to accomplish?
Upvotes: 3
Views: 1275
Reputation: 44248
You cannot directly call child method from a base class, but you can use template:
class A {
public:
template<class T>
void executeMethod( void (T::*method)() )
{
(static_cast<T *>( this )->*method)();
}
};
class B : public A {
public:
void sampleMethod() {}
void childMethod() { executeMethod( &B::sampleMethod ); }
};
But more flexible solution would be to use std::function
and std::bind
as then you can pass methods which signature does not match.
class A {
public:
typedef std::function<void()> Method;
void executeMethod( const Method &method )
{
method();
}
};
class B : public A {
public:
void sampleMethod1() {}
void sampleMethod2( int param ) {}
void childMethod1() { executeMethod( std::bind( &B::sampleMethod1, this ); }
void childMethod2() { executeMethod( std::bind( &B::sampleMethod2, this, 123 ); }
};
Upvotes: 2
Reputation: 1356
To make a callable object bound to a member function you should use std::bind. This will create a forwarding wrapper which will call sampleMethod with some of its parameters pre specified. In this case, the "this" parameter will be bound.
std::bind(&B::sampleMethod, this);
Upvotes: 1
Reputation: 206577
typedef void(A::*METHOD);
defines METHOD
to be a pointer of type void*
to a member variable of A
, not a pointer to a member function of A
.
You need:
typedef void (A::*METHOD)();
Even with that change, you can't use a member function of B
to pass as an argument where METHOD
is expected.
You can make the function that you want to pass a virtual member function of A
and use it.
class A {
protected:
typedef void(A::*METHOD)();
void executeMethod(METHOD arg){};
public:
virtual void sampleMethod() = 0;
};
class B : public A {
virtual void sampleMethod(){};
void childMethod(){
this->executeMethod(&A::sampleMethod);
}
};
Upvotes: 2
Reputation: 96241
The problem is that sampleMethod
isn't a member of A
, it's a member of B
and can't convert to a void(A::*)
.
Did you consider using virtual methods perhaps?
Upvotes: 2