Generics in C++: Why They Are Needed and How to Use Templates

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Introduction: What are Generics in C++ and Why Are They Needed?



In the world of programming, there is often a need to write code that works equally well with different data types. For example, an array sorting function should be able to sort both integers and strings or user-defined objects. Without a mechanism for generic programming (generics), one would have to write separate functions for each type, leading to code duplication, errors, and increased maintenance complexity.



In C++, this problem is solved by templates — a powerful tool that allows you to create generic functions and classes. The concept of generics in C++ is implemented precisely through templates. They allow the programmer to define an algorithm or data structure without being tied to a specific type, and instead substitute the type at compile time.



The main advantages of using templates:

  • Reduced code duplication — one template replaces many overloaded functions.
  • Type safety — all type checks are performed at compile time.
  • Performance — templates add no runtime overhead, as code is generated separately for each specific type.
  • Flexibility — you can create complex generic constructs, including containers (STL) and algorithms.


In this article, we will thoroughly examine how to use templates in C++, starting with simple examples and ending with advanced techniques.



Basics of Working with Function Templates



The simplest way to get acquainted with generics is to write a template function. Suppose we need a function that finds the maximum of two values. Without templates, we would have to write overloads for int, double, std::string, etc. With templates, this is done once:



#include <iostream>#include <string>

// Function templatetemplate <typename T>T max(T a, T b) { return (a > b) ? a : b;}

int main() { std::cout << max(10, 20) << std::endl; // int std::cout << max(3.14, 2.71) << std::endl; // double std::cout << max("apple", "orange") << std::endl; // const char* (string comparison) return 0;}


Here, the keyword template declares a template, and typename T (or class T) specifies the type parameter. The compiler automatically generates a version of the function for each type used. It is important to note that the types must support the > operator — otherwise a compilation error will occur.



You can also specify multiple type parameters:



template <typename T1, typename T2>void printPair(T1 a, T2 b) {    std::cout << "(" << a << ", " << b << ")" << std::endl;}

// UsageprintPair(42, "Hello"); // (42, Hello)


Class Templates: Creating Universal Containers



Class templates allow you to create generic data structures — this is the foundation of the Standard Template Library (STL). Let's look at a simple example of a template class for a dynamic array:



#include <iostream>#include <stdexcept>

template <typename T>class Array {private: T* data; size_t size;public: Array(size_t sz) : size(sz) { data = new T[size]; } ~Array() { delete[] data; } T& operator[](size_t index) { if (index >= size) { throw std::out_of_range("Index out of range"); } return data[index]; } size_t getSize() const { return size; }};

int main() { Array<int> intArray(5); // Array of integers Array<double> doubleArray(3); // Array of floating-point numbers

Blogs

Book Recommendations