Inheritance is one of the most used method for code reuse. Object Oriented Languages strive on the inheritance to collect the common functionality in a base class. What is Polymorphism? From : stackoverflow If you think about the Greek roots of the term, it should become obvious. Poly = many: polygon = many-sided, polystyrene = many styrenes (a), polyglot = many languages, and so on.Morph = change or form: morphology = study of biological form, Morpheus = the Greek god of dreams able to take any form. So polymorphism is the ability (in programming) to present the same interface for differing underlying forms (data types). Polymorphism in C++ C++ support both Dynamic and Static Polymorphism. In this type of polymorphism, the type of the object is not known at compile time ( maybe based on user input, etc), and thus compiler adds extra data structure to support this. The standard doesn't dictate on how it should be implemented. Dynamic Polymorphism : In this type, the type of the object is known at the compile time itself and hence there is no need to actually save extra information in the data structure. But as mentioned in before, we need to know the type of the object at compile time. Static Polymorphism : Static Polymorphism using the Curiously Recurring Template Pattern Since this article is about static polymorphism, we will brush aside all the discussion on dynamic polymorphism. Let's try to simulate calling different Binary Operators. In the grand-scheme of things this can be used when one wants their own Expression Template Library. Let's see a simple example code. < Derived> { <Derived*>( )->implementation(x, y); } }; template typename { struct BinaryOperator float interface ( x, y) float float return static_cast this Here we have a base class template (note that this is not a class as it won't instantiated will the Derived Type is known) with the interface method which calls the implementation of the derived class. BinaryOperator BinaryOperator<Add>{ { :: << << :: ; x + y; } }; BinaryOperator<Subtract>{ { :: << << :: ; x - y; } }; : struct Add float implementation ( x, y) float float std cout "Implementation Add" std endl return : struct Subtract float implementation ( x, y) float float std cout "Implementation Sub" std endl return These are our derived classes for the . It is after looking at that the compiler generates a specialised base class for the and similarly for . BinaryOperator BinaryOperator<Add> Add Subtract So now if we create objects of our derived classes and hold a reference to them using our base class, we can call the interface. This call will dispatch to the implementation of derived class. { :: << :: ; BinaryOperator<Add>&& add = Add{}; BinaryOperator<Subtract>&& subtract = Subtract{}; :: << add.interface( , ) << :: ; :: << subtract.interface( , ) << :: ; :: << :: ; } int main () std cout std endl std cout 4 5 std endl std cout 4 5 std endl std cout std endl As expected the calls for add.interface will be dispatched to implementation and similarly for . Add's Subtract Implementation Add Implementation Sub 9 -1 Here is the whole code snippet. < Derived> { <Derived*>( )->implementation(x, y); } }; BinaryOperator<Add>{ { :: << << :: ; x + y; } }; BinaryOperator<Subtract>{ { :: << << :: ; x - y; } }; { :: << :: ; BinaryOperator<Add>&& add = Add{}; BinaryOperator<Subtract>&& subtract = Subtract{}; :: << add.interface( , ) << :: ; :: << subtract.interface( , ) << :: ; :: << :: ; } # include <iostream> template typename { struct BinaryOperator float interface ( x, y) float float return static_cast this : struct Add float implementation ( x, y) float float std cout "Implementation Add" std endl return : struct Subtract float implementation ( x, y) float float std cout "Implementation Sub" std endl return int main () std cout std endl std cout 4 5 std endl std cout 4 5 std endl std cout std endl If one is not happy with explicitly working with floats, then we can also take the as template parameter. DataType < Derived, DataType> { <Derived*>( )->implementation(x, y); } }; < DataType> BinaryOperator<Add<DataType>, DataType>{ { :: << << :: ; x + y; } }; < DataType> BinaryOperator<Subtract<DataType>, DataType>{ { :: << << :: ; x - y; } }; < DType, < > op(x, y); } { DType = ; :: << :: ; DType x = ; DType y = ; :: << execute(Add<DType>{}, x, y) << :: ; :: << execute(Subtract<DType>{}, x, y) << :: ; :: << :: ; } # include <iostream> template typename typename { struct BinaryOperator DataType operator () (DataType x, DataType y) return static_cast this template typename : struct Add DataType implementation (DataType x, DataType y) std cout "Implementation Add" std endl return template typename : struct Subtract DataType implementation (DataType x, DataType y) std cout "Implementation Sub" std endl return template typename template typename > ( <DType> , , ){ class Op DType execute Op op DType x DType y return int main () using double std cout std endl 4 5 std cout std endl std cout std endl std cout std endl Thanks for reading!