The reason that this doesn't work is because templated functions are not instantiated (compiled into binary code) until they are used. The vtable needs an actual address to point to, and is generated at the time that the class is. As a templated function could have any type, it would be impossible for a vtable to be generated that would be big enough to accept any type. Well, maybe it could, but it would be impractical.
A possible way around this is to accept a proxy:
#include <assert.h>
class unexpected_type : std::exception {
char const* what() override { return "Unexpected type passed"; }
};
enum types
{
int_e, float_e
};
class Base
{
virtual int func(types) = 0;
};
class Child
{
int func_int() { return 1; }
int func_float() { return 0; };
int funct(types type) {
switch(type) {
case int_e: return func_int();
case float_e: return func_float();
default:
assert(false);
throw unexpected_type();
}
};
void main()
{
Base* p = new Child();
int i = p->func(int_e);
int j = p->func(float_e);
delete p;
}
Note that this is just one way. Another possible method would be to use a class proxy that can have a virtual function to be able to tell the programme what to do next. The virtual function would then accept the base class. You might want to lookup
type erasure c++.
HTH
A