Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass base class pointer in a CRTP implementation

Tags:

c++

crtp

I am converting my code having plain inheritance with pure virtual methods into CRTP to avoid overhead of virtual methods (see here).

The conversion works perfectly fine till I remove the comment on call method in the CRTP implementation (It gives compilation error: use of undeclared identifier 'T') How do I implement the same call method in CRTP which gives no problem in plain inheritance? In other words, is it possible to pass a pointer to base class as in plain inheritance?

Of course, I can solve the problem by moving the call method inside the class template, but for my use case, it does not belong there (I have not given my actual code here, which is quite long). Any ideas?

Code before conversion looks like:

#include <iostream>

class Base
{
public:
    void interface() {
        implementation();
    }
    virtual void implementation() = 0;
};

class Derived1 : public Base
{
public:
    void implementation() {
        std::cout << "Hello world 1" << std::endl;
    }
};

class Derived2 : public Base
{
public:
    void implementation() {
        std::cout << "Hello world 2" << std::endl;
    }
};

void call(Base *b) {
    b->interface();
    // ... do other things ...
}

int main() {
   Derived1 d1;
   Derived2 d2;
   call(&d1);
   call(&d2);
}

Code after conversion (CRTP) looks like:

#include <iostream>

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

class Derived1 : public Base<Derived1>
{
public:
    void implementation() {
        std::cout << "Hello world 1" << std::endl;
    }
};

class Derived2 : public Base<Derived2>
{
public:
    void implementation() {
        std::cout << "Hello world 2" << std::endl;
    }
};

//void call(Base<T> *b) {
//    b->interface();
//    // ... do other things ...
//}

int main() {
   Derived1 d1;
   Derived2 d2;
   //call(&d1);
   //call(&d2);
   d1.interface();
   d2.interface();
}
like image 611
arun Avatar asked Oct 14 '25 14:10

arun


1 Answers

You missed some syntax. Correct declaration:

template<class T> // <--- this was missing
void call(Base<T> *b) {
    b->interface();
}
like image 114
Maxim Egorushkin Avatar answered Oct 17 '25 02:10

Maxim Egorushkin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!