first off: I have read and I know now that a virtual template member function is not (yet?) possible in C++. A workaround would be to make the class a template and then use
Per Mikael's post, I have made another offshoot, using the CRTP and following Eigen's style of using derived() for an explicit subclass reference:
// Adaptation of Visitor Pattern / CRTP from:
// http://stackoverflow.com/a/5872633/170413
#include
using std::cout;
using std::endl;
class Base {
public:
virtual void tpl(int x) = 0;
virtual void tpl(double x) = 0;
};
// Generics for display
template
struct trait {
static inline const char* name() { return "T"; }
};
template<>
struct trait {
static inline const char* name() { return "int"; }
};
template<>
struct trait {
static inline const char* name() { return "double"; }
};
// Use CRTP for dispatch
// Also specify base type to allow for multiple generations
template
class BaseImpl : public BaseType {
public:
void tpl(int x) override {
derived()->tpl_impl(x);
}
void tpl(double x) override {
derived()->tpl_impl(x);
}
private:
// Eigen-style
inline DerivedType* derived() {
return static_cast(this);
}
inline const DerivedType* derived() const {
return static_cast(this);
}
};
// Have Child extend indirectly from Base
class Child : public BaseImpl {
protected:
friend class BaseImpl ;
template
void tpl_impl(T x) {
cout << "Child::tpl_impl<" << trait::name() << ">(" << x << ")" << endl;
}
};
// Have SubChild extend indirectly from Child
class SubChild : public BaseImpl {
protected:
friend class BaseImpl;
template
void tpl_impl(T x) {
cout << "SubChild::tpl_impl<" << trait::name() << ">(" << x << ")" << endl;
}
};
template
void example(BaseType *p) {
p->tpl(2);
p->tpl(3.0);
}
int main() {
Child c;
SubChild sc;
// Polymorphism works for Base as base type
example (&c);
example (&sc);
// Polymorphism works for Child as base type
example(&sc);
return 0;
}
Output:
Child::tpl_impl(2)
Child::tpl_impl(3)
SubChild::tpl_impl(2)
SubChild::tpl_impl(3)
SubChild::tpl_impl(2)
SubChild::tpl_impl(3)
This snippet may be found in source here: repro:c808ef0:cpp_quick/virtual_template.cc