In order to store CRTP object pointers in a homogenous container the templated base class can itself be derived from a class common_base
that defines a pure virtual interface and (if required) a virtual destructor. This is sometimes referred to as the CRTP pitfall workaround.
class common_base
{
public:
virtual ~common_base() {}
};
template<typename T> class base : public common_base {
public:
void func() {
printf("base func()\n");
static_cast<T*>(this)->func();
}
};
class derived : public base<derived> {
public:
void func() {
printf("derived func()\n");
}
};
derived d;
base<derived>& b = d;
d.func(); // Output: derived func()
b.func(); // Output: base func()
// derived func()
All good. Now let's say I want to use the workaround to not only store derived
objects in a container, but to also call a common interface on those objects. So I change common_base
to be:
class common_base
{
public:
virtual ~common_base() {}
virtual void func() = 0;
};
derived d;
base<derived>& b = d;
common_base& c = d;
d.func(); // Output: derived func()
b.func(); // Output: derived func()
c.func(); // Output: derived func()
The above pure virtual function pattern is present in references I've seen but it looks like it causes a vtable to be used in resolving the func()
calls at runtime, which negates the performance benefit of the compile time polymorphism of CRTP. Is it not possible to declare a common base interface with CRTP early binding in this way?
References: