Class Templates

Compile-Time Polymorphism with Templates

Can I use templates to implement compile-time polymorphism?

Illustration representing computer hardware

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:

  1. We define a base Shape template that declares a Draw() function. This function calls DrawImpl() on the derived class using static_cast.
  2. Derived classes (like Circle and Square) inherit from Shape<DerivedClass> and implement their own DrawImpl() method.
  3. The DrawShape() function template can work with any type derived from Shape<T>.
  4. At compile-time, the correct DrawImpl() method is selected based on the actual type of the object.

Key benefits of this approach:

  1. Performance: There's no virtual function call overhead. The correct function is determined at compile-time.
  2. Flexibility: You can add new "derived" classes without modifying existing code.
  3. Static checking: Errors, like forgetting to implement DrawImpl(), are caught at compile-time.

Some considerations:

  1. Code bloat: Each instantiation of the template generates new code, which can increase compile times and binary size.
  2. Debugging: Template-heavy code can be more challenging to debug due to complex error messages.
  3. Lack of runtime polymorphism: You can't have containers of mixed shape types or change behavior at runtime.

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.

A computer programmer
Part of the course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

  • 124 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved