Generics in C++: Why They Are Needed and How to Use Them for Beginners

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

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

\n\n

Every programmer sooner or later encounters a situation where they need to write a function that works with different data types. For example, a function to find the maximum element — it should work equally well with int, double, and string. Without special tools, you would have to write a separate implementation for each type. This is where generics (generic types) come to the rescue, or as they are called in C++, templates.

\n\n

In C++, the template mechanism is the foundation of generic programming. It allows you to write code that works with any data type without sacrificing performance. In this article, we will break down what generics in C++ are, why they are needed, and how to use them in practice. The material is designed for beginners, so we will move from simple to complex.

\n\n

What are Templates (Generics) in C++?

\n\n

A template is a construct that allows you to define a function or class that works with an arbitrary data type. Instead of a specific type, you specify a type parameter (for example, T), and the compiler substitutes the required type during compilation. This is called template instantiation.

\n\n

Imagine a cookie cutter. The cutter is one, but cookies can be made from different dough: shortbread, chocolate, oatmeal. The template is the cutter, and the type (int, double, string) is the dough. You describe the algorithm once, and the compiler automatically creates versions for the required types.

\n\n

There are two types of templates:

\n
    \n
  • Function templates — for creating generic functions.
  • \n
  • Class templates — for creating generic classes (e.g., containers).
  • \n
\n\n

Function Templates: The First Step to Generic Code

\n\n

Let's start with the simplest — a template function. Suppose we need a function that returns the maximum of two values. Here is what it looks like without templates:

\n\n
int max_int(int a, int b) {\n    return (a > b) ? a : b;\n}\n\ndouble max_double(double a, double b) {\n    return (a > b) ? a : b;\n}
\n\n

The code is duplicated. With a template, this is solved elegantly:

\n\n
#include <iostream>\n#include <string>\n\ntemplate <typename T>\nT max_value(T a, T b) {\n    return (a > b) ? a : b;\n}\n\nint main() {\n    std::cout << max_value(10, 20) << std::endl;           // 20\n    std::cout << max_value(3.14, 2.71) << std::endl;       // 3.14\n    std::cout << max_value(std::string("apple"), \n                             std::string("banana")) << std::endl; // banana\n    return 0;\n}
\n\n

The keyword template tells the compiler that this is a template. <typename T> is the list of template parameters. T is a placeholder name for the type that will be substituted later. Instead of typename, you can use class — there is no difference:

\n\n
template <class T>\nT max_value(T a, T b) {\n    return (a > b) ? a : b;\n}
\n\n

When you call max_value(10, 20), the compiler sees that the arguments are int and automatically creates a version of the function for int. This process is called type deduction. If needed, you can explicitly specify the type:

\n\n
std::cout << max_value<double>(5, 7.5) << std::endl; // 7.5
\n\n

Important: a template function must be defined in a header file (or before its use), because the compiler needs to see the full definition for instantiation.

\n\n

Class Templates: Creating Universal Containers

\n\n

Class templates are an even more powerful tool. The most prominent example is the containers from the standard library (STL): std::vector<int>, st

Blogs

Book Recommendations