Skip to main content

Section 23.1 Templates

In C++, templates allow us to write code that works with different data types without duplicating the same logic. A template defines a general form of a function (or classes or variables), and the compiler automatically generates the specific versions when the function is used.
Suppose we want to write a function that finds the maximum of two values. Without templates, we would need to write separate functions for each data type that we want to work with:
Listing 23.1.1.
int myMax(int a, int b) {
    return (a > b) ? a : b;
}

double myMax(double a, double b) {
    return (a > b) ? a : b;
}
Other than the return types and parameter types, the logic inside the functions is identical. Writing the same code multiple times violates the DRY (Donโ€™t Repeat Yourself) principle. To avoid this repetition, we can use templates:
Listing 23.1.2.
template <typename T>
T myMax(T a, T b) {
    return (a > b) ? a : b;
}
Before the function prototype is the template declaration. It specifies that the following function is a template function and can operate on different data types. It also specifies the type parameter T, which will be replaced with the actual data type when the function is called. You can think of <typename T> as saying โ€œthis template works with any one data type that we will refer to as Tโ€.

Aside

Then in the function definition itself, we use T as the type for the parameters and the return value. This says โ€œwhatever type T is, use that as the return type and parameter typesโ€.
When we call the function, the compiler automatically generates the appropriate version based on the argument types. For example, if we call myMax(3, 5), the compiler creates a version of myMax where T is int. If we call myMax(3.5, 2.1), it creates a version where T is double .
In this code sample, the templated version of myMax will be used to generate three different concrete versions of the code, one each for int, double, and char:
Listing 23.1.3.

Insight 23.1.1.

Templates are not compiled directly. They are a blueprint for generating code. When you use templated code, the compiler uses that blueprint to create the specific versions needed for the types you use.
If the compiler canโ€™t determine what type T is supposed to be, it will result in a compilation error. For example, if we try to call myMax with an int and a double, the compiler wonโ€™t know if it should use int or double for T:
Listing 23.1.4.
To resolve this ambiguity, we can explicitly specify the type when calling the function by placing <TYPENAME> after the function name. When we do this, the compiler knows exactly which type to use for T. It will try to convert any other types will be converted to the specified type:
Listing 23.1.5.

Note 23.1.2.

The name<TYPENAME> syntax should look familiar from working with vectors. That is not a coincidenceโ€”vectors are a templated type!
You have attempted of activities on this page.