Search code examples
c++static-polymorphism

Is emulating pure virtual function in static polymorphism using CRTP possible?


I'm trying to implement compile-time polymorphism using CRTP, and want to force the derived class to implement the function.

The current implementation is like this.

template <class Derived>
struct base {
    void f() {
        static_cast<Derived*>(this)->f();
    }
};

struct derived : base<derived>
{
    void f() {
    ...
    }
};

In this implementation, call to the function falls into an infinite loop if the derived class didn't implement f().

How do I force the derived class to implement the function like pure virtual function? I tried to use 'static_assert' like static_assert(&base::f != &Derived::f, "...") but it generates an error message saying that two member function pointers pointing to the different classes' member functions are not comparable.


Solution

  • 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"); }
    };