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

crtp vs virtual functions
c++ static polymorphism
c++ crtp static polymorphism
crtp example
c++ static polymorphism container
c++ static polymorphism interface
crtp mixin
crtp multiple inheritance

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.


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

c++ - Confusion about CRTP static polymorphism, as I would with normal inheritance and virtual functions, due to Base being templated, but I The thing is that the description of CRTP as "static polymorphism" is not really Of course, CRTP is a purely compile-time construct. Is emulating pure virtual function in static polymorphism using CRTP possible? Curiously Recurring Template Pattern . The "Curiously Recurring Template Pattern" (CRTP) is a commonly used alternative to dynamic binding. CRTP is used to implement static polymorphism (aka simulated dynamic binding) . Static polymorphism achieves a similar effect to the use of virtual functions, allowing the overloaded functions in the derived classes to be selected at compile time rather than at run time.


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...)) {}
};

Curiously recurring template pattern, The curiously recurring template pattern (CRTP) is an idiom in C++ in which a class X derives from a class template instantiation using X itself as template argument. More generally it is known as F-bound polymorphism, and it is a form of Some use cases for this pattern are static polymorphism and other metaprogramming� You can use CRTP in this case as well by using static_cast to cast the Base type to the derived type specified by the template parameter. Like this: static_cast< Derived * >( this )->someFunctionImpl(); So even though there’s not a virtual function involved, you still get polymorphic dispatching, just without the overhead of vtables.


Through this is a question asked years ago but I've encountered this recently, so I'll just post it here hope it might help some people.

Using auto as return type might be another solution. Consider the following code:

template<typename Derived>
class Base
{
  public:
    auto f()
    {
        static_cast<Derived*>(this)->f();
    }
};

If the derived class doesn't provide a valid overload, then this function becomes recursive, and since auto requires the final return type, it can never be deduced, thus would be guaranteed to throw an compilation error. For example on MSVC it's something like:

a function that returns 'auto' cannot be used before it is defined

This forces derived class to provide implementation, just like pure virtual function.

The good thing is no extra code is needed, and if the derived class also use auto as return type then this chain can go as long as required. In some cases it can be convenient and flexible, as in Base and LevelTwo in following code, which can return different types when calling the same interface f. However this chain totally disables direct inheritance of implementation from base class, as in LevelThree:

template<typename Derived = void>
class Base
{
  public:
    Base() = default;
    ~Base() = default;

    // interface
    auto f()
    {
        return fImpl();
    }
  protected:
    // implementation chain
    auto fImpl()
    {
        if constexpr (std::is_same_v<Derived, void>)
        {
            return int(1);
        }
        else
        {
            static_cast<Derived*>(this)->fImpl();
        }
    }
};

template<typename Derived = void>
class LevelTwo : public Base<LevelTwo>
{
  public:
    LevelTwo() = default;
    ~LevelTwo() = default;

    // inherit interface
    using Base<LevelTwo>::f;
  protected:
    // provide overload
    auto fImpl()
    {
        if constexpr (std::is_same_v<Derived, void>)
        {
            return float(2);
        }
        else
        {
            static_cast<Derived*>(this)->fImpl();
        }
    }

    friend Base;
};

template<typename Derived = void>
class LevelThree : public LevelTwo<LevelThree>
{
  public:
    LevelThree() = default;
    ~LevelThree() = default;

    using LevelTwo<LevelThree>::f;

  protected:
    // doesn't provide new implementation, compilation error here
    using LevelTwo<LevelThree>::fImpl;

    friend LevelTwo;
};

In my case, the derived class I work on also derive from another class which provides extra information needed to determine whether to stop at current class or go for derived class. But in other cases, either break the chain using actual types instead of 'auto', or use some other tricks. But in situations like that maybe virtual function is the best chose.

How to Turn a Hierarchy of Virtual Methods into a CRTP, In our case, the class is not designed to be used with dynamic polymorphism ( see below) and pointers to base class. So I haven't left the virtual� Interface vs Abstract Classes: An interface does not have implementation of any of its methods, it can be considered as a collection of method declarations. In C++, an interface can be simulated by making all methods as pure virtual. In Java, there is a separate keyword for interface.


Static Polymorphism in C++, Of course, you don't have to use CRTP with static methods. This entry was posted in C/C++ and tagged polymorphism, virtual functions. A couple of years ago I wrote an article about the Curiously Recurring Template Pattern in C++, focusing on the motivation behind it and how to implement it.. That article mentioned runtime performance as the main reason for employing CRTP instead of the more traditional runtime polymorphism (dispatch via virtual functions).


In C++ why and how are virtual functions slower?, Basically, the code for a static ("normal") call is: Copy some registers on the stack, to allow the called function to use those registers. Copy the� I use in the function template execute (line 29 - 32) static polymorphism. I invoke on each argument base the method base.interface. The method Base::interface in line 7 - 9 is the key point of the CRTP idiom. The methods dispatches to the implementation of the derived class: static_cast<Derived*>(this)->implementation(). That is possible


User tmyklebu, Is emulating pure virtual function in static polymorphism using CRTP possible? stackoverflow.com. 9 � Should Theoretical Computer Science SE and� Virtual Table usage with pure virtual functions calls : update() and handle_one_message(msg). CRTP to the rescue ? Curiously recurring template pattern (CRTP) , is a C++ idiom in which a class derive from a template class instanciation that use the first one as template argument.