C++ templates are a powerful feature added to C++ for implementing generic programming. They allow you to define generic classes and functions, thereby supporting generic programming. Generic programming is a technique where generic types are used as parameters in algorithms so that they can be applied to various data types.
Templates can be represented in two ways:
-
Function Templates
-
Class Templates
Function Template:
We can define a template for a function. For example, if we have an add() function, we can create different versions of the add function to add integers, floats, or doubles.
Class Template:
We can define a template for a class. For example, a class template can be created for an array class that can accept different types of arrays, such as integer arrays, float arrays, or double arrays.
đŸ‘‡ Click to Claim đŸ‘‡
đŸ‘‰ C Language Knowledge Resource Collection
Function Templates
-
Generic functions use the concept of function templates. Generic functions define a set of operations that can be applied to different types of data.
-
The data type of the operation in the function depends on the data type of the parameters passed.
-
For example, the quicksort algorithm uses a generic function implementation that can be applied to integer arrays or float arrays.
-
Generic functions can be created using the keyword template. The template defines the operations that the function will perform.
Syntax of Function Templates
template < class Ttype > ret_type func_name(parameter_list){ // function body.}
Where, Ttype: This is the placeholder name for the data type used by the function. It is used inside the function definition. It is just a placeholder, and the compiler will automatically replace it with the actual data type.
class: The class keyword is used to specify the generic type in the template declaration.
Let’s look at a simple example of a function template:
#include <iostream>
using namespace std;
template<class T> T add(T &a, T &b){ T result = a + b; return result;}
int main(){ int i = 2; int j = 3; float m = 2.3; float n = 1.2; cout << "Addition of i and j is: " << add(i, j); cout << '\n'; cout << "Addition of m and n is: " << add(m, n); return 0;}
Output:
Addition of i and j is: 5
Addition of m and n is: 3.5
In the example above, we created a function template that can perform addition on any type (integer, float, or double).
Function Templates with Multiple Parameters
We can separate multiple generic types in the template function using commas, allowing the use of multiple generic types in the template function.
Syntax
template<class T1, class T2,.....>return_type function_name (arguments of type T1, T2....){ // function body.}
In the above syntax, we can see that the template function can accept any number of different types of parameters.
Let’s look at a simple example:
#include <iostream>
using namespace std;
template<class X,class Y> void fun(X a,Y b) { std::cout << "Value of a is: " << a << std::endl; std::cout << "Value of b is: " << b << std::endl; }
int main() { fun(15,12.3); return 0;}
Output:
Value of a is: 15
Value of b is: 12.3
In the example above, we used two generic types in the template function, namely X and Y.
Overloading Function Templates
We can overload generic functions, meaning the overloaded template functions differ in their parameter lists.
Let’s understand this with a simple example:
#include <iostream>
using namespace std;
template<class X> void fun(X a){ std::cout << "Value of a is: " << a << std::endl; }
template<class X,class Y> void fun(X b ,Y c){ std::cout << "Value of b is: " << b << std::endl; std::cout << "Value of c is: " << c << std::endl;}
int main(){ fun(10); fun(20,30.5); return 0;}
Output:
Value of a is: 10
Value of b is: 20
Value of c is: 30.5
In the example above, the fun() function template was overloaded.
Limitations of Generic Functions
Generic functions perform the same operation for all versions of the function, just with different data types. Let’s illustrate this with a simple example of an overloaded function that cannot be replaced with a generic function.
Let’s understand this with a simple example:
#include <iostream>
using namespace std;
void fun(double a){ cout << "The value of a is: " << a << '\n';}
void fun(int b){ if (b % 2 == 0) { cout << "The number is even"; } else { cout << "The number is odd"; }}
int main(){ fun(4.6); fun(6); return 0;}
Output:
The value of a is: 4.6
The number is even
In the example above, we overloaded a normal function. We cannot overload a generic function because the two functions have different functionalities. The first function displays a value, while the second function determines whether the number is even or odd.
Class Templates
Class templates can be defined similarly to function templates. When a class uses the concept of templates, it is referred to as a generic class.
Syntax:
template<class Ttype>class class_name{ // ...};
Ttype is a placeholder that will be determined when the class is instantiated. We can define multiple generic data types using a comma-separated list. Ttype can be used within the class.
Now, let’s create an instance of a class:
class_name<type> ob;
Where,
-
class_name: The name of the class.
-
type: The type of data the class operates on.
-
ob: The name of the object.
Let’s look at a simple example:
#include <iostream>
using namespace std;
template<class T>class A{ public: T num1 = 5; T num2 = 6; void add(){ cout << "The sum of num1 and num2 is: " << num1 + num2 << endl; }};
int main(){ A<int> d; d.add(); return 0;}
Output:
The sum of num1 and num2 is: 11
In the example above, we created a template for class A. In the main() function, we created an instance of class A and named it d.
Class Templates with Multiple Parameters:
We can use multiple generic data types in class templates, separated by commas.
Syntax:
template<class T1, class T2, ......>class class_name{ // class body};
Let’s look at a simple example where the class template contains two generic data types:
#include <iostream>
using namespace std;
template<class T1, class T2>class A{ T1 a; T2 b; public: A(T1 x, T2 y) { a = x; b = y; } void display(){ cout << "Values of a and b are: " << a << " ," << b << endl; }};
int main(){ A<int, float> d(5, 6.5); d.display(); return 0;}
Output:
Values of a and b are: 5, 6.5
Non-Type Template Parameters:
Templates can contain multiple parameters, and in addition to type T parameters, we can also use non-type parameters. Apart from type T parameters, we can use parameters of other types, such as strings, function names, constant expressions, and built-in types. Let’s look at the example below:
template<class T, int size>class array{ T arr[size]; // automatic array initialization};
In this case, the non-type template parameter is size, so the template passes the size of the array as a parameter.
Specify the parameters when creating an object of the class:
array<int, 15> t1; // array containing 15 integers
array<float, 10> t2; // array containing 10 floats
array<char, 4> t3; // array containing 4 characters
Let’s look at a simple example of a non-type template parameter:
#include <iostream>
using namespace std;
template<class T, int size>class A{ public: T arr[size]; void insert(){ int i = 1; for (int j = 0; j < size; j++) { arr[j] = i; i++; } }
void display(){ for (int i = 0; i < size; i++) { cout << arr[i] << " "; } }};
int main(){ A<int, 10> t1; t1.insert(); t1.display(); return 0;}
Output:
1 2 3 4 5 6 7 8 9 10
In the example above, a class template A was created with a non-type template parameter size. The template parameter was specified when creating an object of class A.
Key Points to Remember:
-
C++ supports a powerful feature called templates for implementing the concept of generic programming.
-
Templates allow us to create a family of classes or functions that handle different data types.
-
Template classes and functions eliminate code duplication for different data types, making development simpler and faster.
-
Both class and function templates can use multiple parameters.
-
Template functions can also be overloaded.
-
We can also use non-type parameters as template parameters, such as built-in or derived data types.
Recommended Articles
-
CLion Tutorial – Toolchain Compiler in CLion (IDE Scope)
-
C Language Algorithm – “Inorder Traversal of Binary Trees” Algorithm Problem
-
C++ Tutorial – Detailed Explanation of User-Defined Exceptions in C++ Language