Yes, you can use templates to implement compile-time polymorphism in C++. This is often referred to as static polymorphism or compile-time polymorphism, as opposed to runtime polymorphism achieved through virtual functions and inheritance.
Compile-time polymorphism with templates allows you to write code that works with different types without the overhead of virtual function calls. It's resolved at compile-time, which can lead to better performance compared to runtime polymorphism.
Here's an example demonstrating compile-time polymorphism using templates:
#include <iostream>
#include <list>
#include <vector>
// Base template for Shape
template <typename T>
class Shape {
public:
void Draw() const {
static_cast<const T*>(this)->DrawImpl();
}
};
// Derived "class" Circle
class Circle : public Shape<Circle> {
public:
void DrawImpl() const {
std::cout << "Drawing a circle\n";
}
};
// Derived "class" Square
class Square : public Shape<Square> {
public:
void DrawImpl() const {
std::cout << "Drawing a square\n";
}
};
// Function template that works with any Shape
template <typename T>
void DrawShape(const Shape<T>& shape) {
shape.Draw();
}
int main() {
Circle circle;
Square square;
DrawShape(circle);
DrawShape(square);
// We can even use it with containers
std::vector<Shape<Circle>*> circles = {
new Circle, new Circle
};
std::list<Shape<Square>*> squares = {
new Square, new Square
};
for (auto& c : circles) DrawShape(*c);
for (auto& s : squares) DrawShape(*s);
// Clean up
for (auto& c : circles) delete c;
for (auto& s : squares) delete s;
}
Drawing a circle
Drawing a square
Drawing a circle
Drawing a circle
Drawing a square
Drawing a square
This example demonstrates the Curiously Recurring Template Pattern (CRTP), a form of compile-time polymorphism. Here's how it works:
Shape
template that declares a Draw()
function. This function calls DrawImpl()
on the derived class using static_cast.Circle
and Square
) inherit from Shape<DerivedClass>
and implement their own DrawImpl()
method.DrawShape()
function template can work with any type derived from Shape<T>
.DrawImpl()
method is selected based on the actual type of the object.Key benefits of this approach:
DrawImpl()
, are caught at compile-time.Some considerations:
Compile-time polymorphism with templates is a powerful technique in C++. It's particularly useful in scenarios where you need high performance and know the types you're working with at compile-time. However, it's not a replacement for runtime polymorphism in all cases. The choice between compile-time and runtime polymorphism depends on your specific requirements for flexibility, performance, and design.
Answers to questions are automatically generated and may not have been reviewed.
Learn how templates can be used to create multiple classes from a single blueprint