Reputation: 33579
template <typename... Arguments>
class CCallback
{
public:
template <class TargetClass>
CCallback(TargetClass * target, void (TargetClass::*targetMethod)(Arguments...))
{
}
};
struct TargetClassBase
{
protected:
void f() {}
};
struct TargetClassChild : TargetClassBase
{
void g() {}
void test()
{
CCallback<> callback(this, &TargetClassChild::f);
}
} child;
void main()
{
}
That code doesn't compile in MSVC 2013:
error C2660: 'CCallback<>::CCallback' : function does not take 2 arguments
I don't understand why I get this specific error, and how to make it work. There are no further details about the error logged by the compiler.
And, of course, I can't properly specify that the method belongs to the base class (&TargetClassBase::f
)- taking a pointer to a non-public base method is forbidden.
Upvotes: 1
Views: 190
Reputation: 33579
Expanding on robal's perfectly correct answer, I've rewritten the constructor of my class so that I don't need a manual type cast:
template <class TargetInstanceClass, class TargetMethodClass>
CCallback(TargetInstanceClass * target, void (TargetMethodClass::*targetMethod)(Arguments...))
{
void (TargetInstanceClass::*targetInstanceMethod)(Arguments...) = static_cast<void (TargetInstanceClass::*targetInstanceMethod)(Arguments...)>(targetMethod);
}
Upvotes: 0
Reputation: 368
Problem with your code is that compiler cannot deduce template type TargetClass
in constructor for CCallback
. This is because you pass arguments of types: TargetClassChild*
and void (TargetClassBase::*)()
to constructor. This is not a typo. Even if you write &TargetClassChild::f
this expression still has type: pointer to function returning void in class TargetClassBase and not TargetClassChild as one could expect.
This kind of issues can be solved in two ways:
static_cast<void (TargetClassChild::*)()>(&TargetClassChild::f)
Upvotes: 1