Is emulating pure virtual function in static polymorphism using CRTP possible?
template<typename Derived>
class Base
{
private:
static void verify(void (Derived::*)()) {}
public:
void f()
{
verify(&Derived::f);
static_cast<Derived*>(this)->f();
}
};
If the derived class does not implement f
on its own, the type of &Derived::f
would be void (Base::*)()
, which breaks compilation.
Since C++11 we can also make this function generic with variadic template.
template<typename Derived>
class Base
{
private:
template<typename T, typename...Args>
static void verify(T (Derived::*)(Args...)) {}
};
You can give the thing you override and the hook different names, like this:
template <class Derived>
struct base {
void f() {
static_cast<Derived*>(this)->fimpl();
}
void fimpl() = delete;
};
struct derived : base<derived> {
void fimpl() { printf("hello world\n"); }
};
Here, fimpl = delete
in the base so that it cannot be called accidentally unless fimpl
is overridden in the derived class.
You can also stick an intermediate hiding layer into your CRTP to "temporarily" mark f
as delete
:
template <class Derived>
struct base {
void f() {
static_cast<Derived*>(this)->f();
}
};
template <class Derived>
struct intermediate : base<Derived> {
void f() = delete;
};
struct derived : intermediate<derived> {
void f() { printf("hello world\n"); }
};