Templates Basics in C++

Templates provide the capability to parameterize types in functions and classes. You can define functions or classes with generic types that can be substituted for concrete types by the compiler.

Let us begin with a simple example to demonstrate the need for templates. Suppose you want to find the maximum of two integers, two doubles, two characters, and two strings. You might write four overloaded functions as follows:

1 int maxValue(int value1, int value2)
2 {
3   
if (value1 > value2)
4       
return value1;
5   
else
6       return value2;
7 }
8
9
double maxValue(double value1, double value2)
10 {
11   
if (value1 > value2)
12     
return value1;
13   
else
14      return value2;
15 }
16
17
char maxValue(char value1, char value2)
18 {
19   
if (value1 > value2)
20       
return value1;
21   
else
22       return value2;
23 }
24
25 string maxValue(string value1, string value2)
26 {
27   
if (value1 > value2)
28       
return value1;
29   
else
30       return value2;
31 }

These four functions are almost identical, except that each uses a different type. The first func­tion uses the int type, the second the double type, the third the char type, and the fourth the string type. It would save typing, save space, and make the program easy to maintain if you could simply define one function with a generic type as follows:

1 GenericType maxValue(GenericType value1, GenericType value2)
2 {
3   
if (value1 > value2)
4       
return value1;
5   
else
6       return value2;
7 }

This GenericType applies to all types such as int, double, char, and string.

C++ enables you to define a function template with generic types. Listing 12.1 defines a template function for finding a maximum value between two values of a generic type.

Listing I2.I GenericMaxValue.cpp

1 #include <iostream>
2
#include <string>
3
using namespace std;
4
5
template<typename T>
6 T maxValue(T value1, T value2)
7 {
8   
if (value1 > value2)
9       
return value1;
10   
else
11      return value2;
12 }
13
14
int main()
15 {
16    cout <<
“Maximum between 1 and 3 is ” << maxValue(1, 3) << endl;
17    cout <<
“Maximum between 1.5 and 0.3 is ”
18       << maxValue(1.5, 0.3) << endl;
19    cout <<
“Maximum between ‘A’ and ‘N’ is ”
20       << maxValue(‘A’, ‘N’) << endl;
21    cout <<
“Maximum between \”NBC\” and \”ABC\” is ”
22       << maxValue(string(“NBC”), string(“ABC”)) << endl;
23
24
return 0;
25 }

The definition for the function template begins with the keyword template fol­lowed by a list of parameters. Each parameter must be preceded by the interchangeable keyword typename or class in the form <typename typeParameter> or <class typeParameter>. For example, line 5

template<typename T>

begins the definition of the function template for maxValue. This line is also known as the template prefix. Here T is a type parameter. By convention, a single capital letter such as T is used to denote a type parameter.

The maxValue function is defined in lines 6-12. A type parameter can be used in the func­tion just like a regular type. You can use it to specify the return type of a function, declare function parameters, or declare variables in the function.

The maxValue function is invoked to return the maximum int, double, char, and string in lines 16-22. For the function call maxValue(1, 3), the compiler recognizes that the parameter type is int and replaces the type parameter T with int to invoke the maxValue function with a concrete int type. For the function call maxValue(string(“NBC”), string(“ABC”)), the compiler recognizes that the parameter type is string and replaces the type parameter T with string to invoke the maxVal ue function with a concrete stri ng type.

What happens if you replace maxValue(string(“NBC”), string(“ABC”)) in line 22 with maxValue(“NBC”, “ABC”)? You will be surprised to see that it returns ABC. Why? “NBC” and “ABC” are C-strings. Invoking maxValue(“NBC”, “ABC”) passes the addresses of “NBC” and “ABC” to the function parameter. When comparing value1 > value2, the addresses of two arrays are compared, not the contents of the array!

The parameters in the generic function in Listing 12.1 are defined as pass-by-value. You can modify it using pass-by-reference as shown in Listing 12.2.

Listing 12.2 GenericMaxValuePassByReference.cpp

1 #include <iostream>
2
#include <string>
3
using namespace std;
4
5
template<typename T>
6 T maxValue(
const T& value1, const T& value2)
7 {
8   
if (value1 > value2)
9       
return value1;

10   else
11      return value2;
12 }
13
14
int main()
15 {
16    cout <<
“Maximum between 1 and 3 is ” << maxValue(1, 3) << endl;
17    cout <<
“Maximum between 1.5 and 0.3 is ”
18       << maxValue(1.5, 0.3) << endl;
19    cout <<
“Maximum between ‘A’ and ‘N’ is ”
20       << maxValue(‘A’, ‘N’) << endl;
21    cout <<
“Maximum between \”NBC\” and \”ABC\” is ”
22       << maxValue(string(“NBC”), string(“ABC”)) << endl;
23
24   
return 0;
25 }

Source: Liang Y. Daniel (2013), Introduction to programming with C++, Pearson; 3rd edition.

Leave a Reply

Your email address will not be published. Required fields are marked *