0

Suppose I have textbook example of CRTP (curiously recurring template pattern) and want to create a container of Base* without specifying the Derived information to traverse and call interfaces kind of polymorphically.

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

class Derived1 : public Base<Derived1> {
public:
    void f()
    {
        std::cout << "Derived1::f()\n";
    }
};

class Derived2 : public Base<Derived2> {
public:
    void f()
    {
        std::cout << "Derived2::f()\n";
    }
};

template<typename T>
void apply(Base<T>* ptr) {
    ptr->f();
}


int main() {
    Base<Derived1>* ptr1 = new Derived1;
    Base<Derived2>* ptr2 = new Derived2;
    ptr1->f();
    ptr2->f();
}

Now suppose I want to create a std::vactor (or any other container, not relevant for the question) of Base* and traverse calling f, but compiler doesn't allow as I need to specify the template argument of the Base which pretty much brings to having a vector of Base<Derived1>* or Base<Derived2>*.

Is there a way or trick to get rid of this template argument of create a collection of Base* with different dynamic types?
Thanks in advance.

Eduard Rostomyan
  • 7,050
  • 2
  • 37
  • 76
  • 1
    This is exactly what CRTP can't do. You would need to have a virtual base class for your `Base` class. see [CRTP Pitfalls](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern#Pitfalls) – Stefan Riedel Nov 23 '21 at 12:35
  • 1
    CRTP is used for static polymorphism. Sounds like you want dynamic polymorphism which is achieved with regular inheritance and virtual functions. – interjay Nov 23 '21 at 12:36

0 Answers0