TransWikia.com

Why do I want to use CRTP over simple template for static polymorphism?

Stack Overflow Asked by DiveIntoML on December 18, 2021

I have read a lot of posts about Curiously Recurring Template Pattern and I still do not see why I do not want to use it over just using template programming.

Below is an example slightly modified from Wikipedia:

template <class T> 
struct Base
{
    void interface()
    {
        static_cast<T*>(this)->implementation();
    }
};

struct Derived : Base<Derived>
{
    void implementation();
};

However, I can do exactly the same with just template in a more straightforward way:

template <class T> 
struct OuterClass
{
    void interface()
    {
        nested->implementation();
    }
private:
    T* nested;
};

struct NestedClass
{
    void implementation();
};

OuterClass<NestedClass> x;
x.interface();

What’s the advantage of CRTP over my implementation?

Edit: the line T* nested; as member variable can also be just T nested; so that nested is created by the constructor of outer class.

2 Answers

I can do exactly the same

NO, you have an additional data member "T* nested" which is set during runtime. As this, the compiler has not the full knowledge of the exact object it will see and may optimize less optimal. In addition, you have an indirection via pointer which is not the case if you use "this", as the access to any data member is known at compile time, even if the author of a call has to write static_cast<T*>(this)->something, but the full operation is completely known at compile time.

What you do is more like a virtual function call than compile time polymorphism.

In addition you also have to set the nested pointer somewhere, which means something passed through the constructor, which is also overhead in code and speed.

And at last point I see, you need to create your object in two steps. First the "nested" one and than pass its pointer to the outer class. This can also result in performance drop and can have side effects like non contiguous memory, cache line misses and so on.

Answered by Klaus on December 18, 2021

Solutions provided is pretty much a home-brew of virtual functions-based polymorphism (assuming incomplete sample and having some code elsewhere which actually sets T*)

The main disadvantage of run-time polymorphism (aka type erasure) is performance. Since you need to dereference the pointer, compiler generally has no way of knowing at compile time which function is called, and thus can't inline the function and make decisions on side-effects of the function. On top of that, calling through pointer generally requires an extra step of pointer dereference, which also slows things down.

Answered by SergeyA on December 18, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP