I'm trying to wrap my head around the CRTP. There are some good sources around, including this forum, but I think I have some confusion about the basics of static polymorphism. Looking at the following Wikipedia entry:
template <class T>
struct Base
{
void implementation()
{
// ...
static_cast<T*>(this)->implementation();
// ...
}
static void static_func()
{
// ...
T::static_sub_func();
// ...
}
};
struct Derived : public Base<Derived>
{
void implementation();
static void static_sub_func();
};
I understand that this helps me to have different implementation() variants in derived classes, kinda like a compile-time virtual function. However, my confusion is that I think I cannot have functions like
void func(Base x){
x.implementation();
}
as I would with normal inheritance and virtual functions, due to Base being templated, but I would have to either specify
func(Derived x)
or use
template<class T>
func(T x)
So what does CRTP actually buy me in this context, as opposed to simply shadowing/implementing the method straightforward in Derived::Base?
struct Base
{
void implementation();
};
struct Derived : public Base
{
void implementation();
static void static_sub_func();
};
Base
instance by value, you suffer from object slicing. Pass it by reference or by pointer if you want polymorphic behavior (whether you use static or dynamic polymorphism). – Igor TandetnikBase
is a template. You cannot use justBase &
, you have to provide a template argument:Base<Something> &
. Which meansfunc
will have to be a template too. – Angew is no longer proud of SOBase
. – Angew is no longer proud of SO