Templates in Cpp

Templates in Cpp

Introduction to Templates in Cpp

In this article, we will be looking at templates a simple yet very powerful tool in C++.

A template is a very useful and simple tool in C++. The whole idea of these templates is to make generic functions so that we can pass the data type also as a parameter and don’t need to write different functions for different datatypes.

For example, if we are writing a function to sort a sequence of data but we don’t know what types of data will be passed to that function so we may need to write different functions for different data types, but rather than writing the same for function multiple times for different types we can use the Templates in C++ to make our sort function generic which would sort data of any type.

So, for using the templates tool in C++ we must know two keywords: ‘template’ and ‘typename’, the typename keyword can be replaced with the keyword ‘class’.

How Do Templates Work?

As we already know that templates are a type of static (compile time) polymorphism, they expand at the compilation time. This is similar to macros, the only difference is that the compiler does type-checking before the expansion of the template. In simple words, the source code contains only a function/class but compiled code may contain multiple copies of the same function/class.

Function Templates

We write a generic function that can be used for different data types. Examples of function templates are sort(), max(), min().

See also  High-Level vs Low-Level Language

Let us look at an example:

#include <iostream>
using namespace std;
  
// One function works for all data types.  This would work
// even for user defined types if operator '>' is overloaded
template <typename T> T myMax(T x, T y)
{
    return (x > y) ? x : y;
}
  
int main()
{
    cout << myMax<int>(3, 7) << endl; // Call myMax for int
    cout << myMax<double>(3.0, 7.0)
         << endl; // call myMax for double
    cout << myMax<char>('g', 'e')
         << endl; // call myMax for char
  
    return 0;
}

Output

7
7
g

In the above example, we have passed the type of data along with the data.

Note: Characters are compared in lexicographic order. So as g is lexicographically greater than e, g is printed.

Let us look at another example, let’s implement bubble sort with function templates:

// CPP code for bubble sort
// using template function
#include <iostream>
using namespace std;
  
// A template function to implement bubble sort.
// We can use this for any data type that supports
// comparison operator < and swap works for it.
template <class T> void bubbleSort(T a[], int n)
{
    for (int i = 0; i < n - 1; i++)
        for (int j = n - 1; i < j; j--)
            if (a[j] < a[j - 1])
                swap(a[j], a[j - 1]);
}
  
// Driver Code
int main()
{
    int a[5] = { 10, 50, 30, 40, 20 };
    int n = sizeof(a) / sizeof(a[0]);
  
    // calls template function
    bubbleSort<int>(a, n);
  
    cout << " Sorted array : ";
    for (int i = 0; i < n; i++)
        cout << a[i] << " ";
    cout << endl;
  
    return 0;
}

Output:

Sorted array : 10 20 30 40 50 

Class Templates

Similar to function templates, class templates are useful when a class defines something that is independent of the data type. Can be useful for classes like LinkedList, BinaryTree, Stack, Queue, Array, etc.

Let us look into an example of a class template:

#include <iostream>
using namespace std;
  
template <typename T> class Array {
private:
    T* ptr;
    int size;
  
public:
    Array(T arr[], int s);
    void print();
};
  
template <typename T> Array<T>::Array(T arr[], int s)
{
    ptr = new T[s];
    size = s;
    for (int i = 0; i < size; i++)
        ptr[i] = arr[i];
}
  
template <typename T> void Array<T>::print()
{
    for (int i = 0; i < size; i++)
        cout << " " << *(ptr + i);
    cout << endl;
}
  
int main()
{
    int arr[5] = { 1, 2, 3, 4, 5 };
    Array<int> a(arr, 5);
    a.print();
    return 0;
}

Output:

1 2 3 4 5

Multiple Arguments Template

Now you might get doubt whether there can be more than one argument for the templates. Yes, like normal parameters, we can pass more than one data type as arguments to templates.

See also  LOOPS IN C++

Let us look into an example to understand this:

#include <iostream>
using namespace std;
  
template <class T, class U> class A {
    T x;
    U y;
  
public:
    A() { cout << "Constructor Called" << endl; }
};
  
int main()
{
    A<char, char> a;
    A<int, double> b;
    return 0;
}

Output:

Constructor Called
Constructor Called

In the above example as you can see we have passed multiple types as arguments to the function templates.

We can also specify a default argument for the templates. The following example will help you understand this better:

#include <iostream>
using namespace std;
  
template <class T, class U = char> class A {
public:
    T x;
    U y;
    A() { cout << "Constructor Called" << endl; }
};
  
int main()
{
    A<char> a; // This will call A<char, char>
    return 0;
}

Output:

Constructor Called

Now you might ask, what is the difference between function overloading and templates?

The answer is simple. Function overloading is used when we perform a similar operation for a variable number of parameter and types, coming to templates we use them when multiple functions do identical operations.

Leave a Comment

Your email address will not be published.

Ads Blocker Image Powered by Code Help Pro
Ads Blocker Detected!!!

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

Refresh