I’m trying to create a template function that accepts pointer to a member functions (non-virtual). I’m working with MSVC2010
The following code works when the problematic line is commented out. The error reported by compiler is pretty explanatory, but I wonder somehow still surprising. How would you recommend working around this problem.
Thanks!
class Foo{
public:
virtual void doFoo() {
std::cout << "In foo" << std::endl;
}
};
class Bar : public Foo{
public:
void doBar() {
std::cout << "In bar" << std::endl;
}
};
template<class A>
void caller(A &a, void (A::*func)()) {
(a.*func)();
}
int _tmain(int argc, _TCHAR* argv[])
{
Bar bar;
bar.doFoo();
caller(bar, &Bar::doBar);
caller(bar, &Bar::doFoo); // this line causes a compiler error
}
This fails on the following error.
error C2782: 'void caller(A &,void (__thiscall A::* )(void))' : template parameter 'A' is ambiguous
1> c:\test\test\test.cpp(23) : see declaration of 'caller'
1> could be 'Foo'
1> or 'Bar'
I can work around the error by changing caller to
template<class A, class B>
void caller(A &a, void (B::*func)()) {
(a.*func)();
}
But this introduces other subtle resolution bugs when considering overload resolutions. Ideally I’d like to only consider functions that can actually be applied to A.
Thanks!
You could use SFINAE to restrict the applicability of the second template
This way, the overload will get out of the way for parameters that would cause a compile error otherwise. For reference, see
std::is_base_of.