Functions III (Templates)
Learn the functionality of templates in C++.
We'll cover the following
Swap multiple data types
When we encounter a scenario where we need to perform an operation on different data types, it can be tempting to write a separate function for each type. However, this can quickly lead to redundant code and make maintenance of the program code difficult.
For example, we have a swap
function that can only swap two integer values. What if we have to swap int
, double
, and float
values in our program? One possible solution is to write a separate swap
function for each data type.
If we define a separate swap
function for each data type, our program would look like the following code:
#include <iostream>using namespace std;void swap_value_int(int &a, int &b){int temp = a;a = b;b = temp;}void swap_value_float(float &a, float &b){float temp = a;a = b;b = temp;}int main(){int num1 = 5;int num2 = 4;cout << "Before Swap" << '\n';cout << "num1 : " << num1 << '\n';cout << "num2 : " << num2 << '\n';swap_value_int(num1, num2);cout << "After Swap" << '\n';cout << "num1 : " << num1 << '\n';cout << "num2 : " << num2 << '\n';float num3 = 5.2;float num4 = 4.1;cout << "Before Swap" << '\n';cout << "num3 : " << num3 << '\n';cout << "num4 : " << num4 << '\n';swap_value_float(num3, num4);cout << "After Swap" << '\n';cout << "num3 : " << num3 << '\n';cout << "num4 : " << num4 << '\n';return 0;}
In SwapWithDifferentNames.cpp
:
Lines 3–8: We implement the
swap_value_int
function for swapping theint
values.Lines 9–14: We implement the
swap_value_float
function for swapping thefloat
values.
In SwapWithFunctionOverloading.cpp
:
The only difference in this code is that we have named the two functions with exactly the same name,
SWAP()
, but the arguments are different. This is called .function overloading Two or more functions with the same name but different parameters.
In the example above, we have implemented the swapping functionality for both data types int
and float
. What if we have two more swapping data types that need to be implemented for this purpose? This is not efficient because, for each data type, we will need a separate function.
Can we avoid this?
Template functions
In C++, a template function can operate on different types of data without the need for separate implementations for each type. It allows us to write a single function that can work with different data types, such as integers, floats, or even custom data types, without having to create separate functions for each type.
Template functions are defined using a special syntax that includes the template
keyword followed by a list of template parameters, which can be either type names or non-type parameters like integers or pointers. These parameters are used to define a generic function that can be instantiated with different data types at compile-time.
For example, consider the following template function provided by C++ that calculates the maximum value between two values:
template <typename T>T max(T a, T b){return (a > b) ? a : b;}
Here, the typename T
is a template parameter that represents a type. This function can be used to find the maximum value between two integers, floats, or any other data type that supports the >
operator.
Let’s test the max function above.
#include <iostream>using namespace std;int main(){int a = 10, b = 20;float c = 3.14, d = 2.71;// Use the max function with different typescout << max(a, b) << endl; // Output: 20cout << max(c, d) << endl; // Output: 3.14return 0;}
Using template functions, we can write more generic and reusable code that works with different data types while avoiding the need to write separate functions for each one.
How does it work?
Let’s look at another implementation of the swap
function. This time, we will make it generic enough that it will run for any data type.
#include <iostream>using namespace std;template<class T>void swap_value(T &a, T &b){T temp = a;a = b;b = temp;}int main(){int num1 = 5;int num2 = 4;swap_value(num1, num2);float num3 = 5.2;float num4 = 4.1;swap_value(num3, num4);return 0;}
The compiler identifies the desired types for which we want to execute the generic function but doesn’t create copies of that function with all the types at compile-time. Instead, it generates a version of the function at the point where the function is called with the specific type. This process is called instantiation.
When we call the function with a specific type, the compiler generates a version of that function with the given type and compiles it. This way, the compiler generates the function definition only for the specific type(s) it needs at runtime rather than creating copies for all possible types.
Therefore, the behavior of the templates can be described as a mechanism for generating code for different types at compile-time based on the code written using a generic type.
Let’s see how templates work by executing the code with proper messages printed on the console for various data types.
#include <iostream>using namespace std;template<class T>void swap_value(T &a, T &b){T temp = a;a = b;b = temp;}int main(){int num1 = 5;int num2 = 4;cout<<"Before Swap"<<'\n';cout << "num1 : " <<num1<<'\n';cout << "num2 : " <<num2<<'\n';swap_value(num1, num2);cout<<"\nAfter Swap"<<'\n';cout << "num1 : " <<num1<<'\n';cout << "num2 : " <<num2<<'\n';float num3 = 5.2;float num4 = 4.1;cout<<"\nBefore Swap"<<'\n';cout << "num3 : " <<num3<<'\n';cout << "num4 : " <<num4<<'\n';swap_value(num3, num4);cout<<"\nAfter Swap"<<'\n';cout << "num3 : " <<num3<<'\n';cout << "num4 : " <<num4<<'\n';return 0;}
Tip: Run the program and see how the
swap_value()
function works with only onetemplate
implementation.
We’ll now solve another nontrivial problem to gain more practice with templates. In particular, we’ll explore how to use a specific function for multiple data types.
Exercise: Generic maximum function
Your task is to create a robust function called MAX()
. It’ll have the following properties:
It takes five input parameters, including integers, floating points, and characters.
It returns the maximum value among the inputs.
The main()
function has already been provided for you to make the task simpler.
Note: You are not allowed to
the overload Writing a separate function for each data type with the same name. MAX()
funtion.
#include <iostream>using namespace std;int main(){int a_i = 3, b_i = 19, c_i = 4, d_i = 14 ,e_i = 12;float a_f = 12.9, b_f = 23.4, c_f = 9.0, d_f = 2.4, e_f = 14.3;char a_c = 'g', b_c = 'e', c_c = 'r', d_c = 'b', e_c = 'l';cout<< MAX(a_i, b_i, c_i, d_i, e_i) << '\n';cout<< MAX(a_f, b_f, c_f, d_f, e_f) << '\n';cout<< MAX(a_c, b_c, c_c, d_c, e_c) << '\n';}