Reputation: 762
I can't seem to figure out what is going on with a particular templated method.
A similar templated method has been in my codebase for a while now and has been used in an identical manner as Bar::Bar(IFoo&)
, the only difference being that the function being passed in is inherited.
I have an interface IFoo
which defines the templated function in question.
struct IFoo {
template<class T>
void doSomething(bool (T::*method)(int), T *instance) {
std::cout << (instance->*method)(5) << "\n";
}
};
I have a class Bar
which is a child of another class
struct Parent {
virtual bool setValue(int a) { return true; }
};
struct Bar : Parent { };
When I try to use IFoo::doSomething
the compiler just doesn't see the matching function
int main() {
Bar b;
IFoo foo;
foo.doSomething(&Bar::setValue, &b);
}
I get the following compiler message
error: no matching function for call to 'IFoo::doSomething(bool (Parent::*)(int), Bar*)
'
What I'm really surprised about is that I don't get a candidate suggestion that for the templated IFoo::doSomething
function.
C++98 solutions only please.
Upvotes: 2
Views: 59
Reputation: 122228
As the error says, the type of Bar::setValue
is actually bool (Parent::*)(int)
. This interferes with the template parameter deduction for doSomething
because it has two T
s that need to be the same. You can help the compiler with the deduction by casting this
:
int main() {
Bar b;
IFoo foo;
foo.doSomething(&Bar::setValue, static_cast<Parent*>(&b));
}
Thanks to JVApen for pointing out that alternatively you can make doSomething
more generic by allowing two different types and let Callback
do the conversion:
template<class T, class U>
void doSomething(bool (T::*method)(int), U *instance);
Upvotes: 2