0

According to my understanding CRTP(Curiously Recurring Template Pattern) is used when a class is derived from a specialization of a templated-base class. So the base class can access the functionality of derived class then delegate to derived class after casting the Parameter to a derived class. Here is an example:

#include <iostream>
using namespace std;


template< class T> 
class Shape2D{
    public:
        Shape2D(double, double);
        virtual ~Shape2D();

        void SetDims(double dim1, double dim2) {
            static_cast<T*>(this)->SetDims(dim1, dim2);
        }

        double GetDim1() const;
        double GetDim2() const;
        double GetSurface()const;
        double GetPerim()const;
};

template<class T>
Shape2D<T>::Shape2D(double dim1, double dim2) {
    static_cast<T*>(this)->SetDims(dim1, dim2);
}

template<class T>
Shape2D<T>::~Shape2D() {

}


template<class T>
double Shape2D<T>::GetSurface()const {
    return static_cast<const T*>(this)->GetSurface();
}

template<class T>
double Shape2D<T>::GetDim1()const {
    return static_cast<const T*>(this)->GetDim1();
}

template<class T>
double Shape2D<T>::GetDim2()const {
    return static_cast<const T*>(this)->GetDim2();
}

template<class T>
double Shape2D<T>::GetPerim()const {
    return static_cast<const T*>(this)->GetPerim();
}

class Rectangle : public Shape2D<class Rectangle> {
    public:
        Rectangle(double, double);

        void SetDims(double, double);

        double GetDim1() const;
        double GetDim2() const;
        double GetSurface()const;
        double GetPerim()const;

        private:
            double itsLength, itsWidth;
};

Rectangle::Rectangle(double len, double wid) :
    itsLength(len), itsWidth(wid), Shape2D<Rectangle>(len, wid) {

}

void Rectangle::SetDims(double len, double wid) {
    itsLength = len;
    itsWidth = wid;
}

double Rectangle::GetDim1()const{
    return itsLength;
}

double Rectangle::GetDim2()const {
    return itsWidth;
}

double Rectangle::GetSurface()const {
    return itsLength * itsWidth;
}

double Rectangle::GetPerim()const {
    return ((itsLength * 2) + (itsWidth * 2));
}

int main() {

    class Rectangle rct(7, 5);
    cout << rct.GetSurface() << endl;
    cout << rct.GetPerim() << endl;

    cout << endl;

    Shape2D<class Rectangle>* pSh2DRect = 
        new Shape2D<class Rectangle>(7, 5);
    cout << "Surface: " << pSh2DRect->GetSurface() << endl;
    cout << "Perimeter: " << pSh2DRect->GetPerim() << endl;

    delete pSh2DRect;


    cout << endl;
    std::cin.get();
}
  • I can't see any benefit above because I can achieve it without CRTP.
  • I want a helpful example to clear my doubts about Static Polymorphism.
  • What if a derived class doesn't inherit from a specialization where this derived class is not the parameter of the template base class?? eg:

    class Parallelogram : public Shape2D<Rectangle>{
         public:
            //...
    };
    

As you can see Parallelogram normally inherit from Shape2D<Parallelogram> not Rectangle. Is it a Undefined Behavior?

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Alex24
  • 600
  • 2
  • 13

0 Answers0