Templates

Template is a powerful feature in any language which enables us to write generic code. Generic code means that it enables us to define functions and classes that can work with different data types with same block of code / same logic. You do not need to write code for different data types explicitly. In this way, your code become reusable. Therefore, we can say that template is a feature in any language that gives that particular language more flexibility.

For example, You are using a function that add two numbers and it is a template function. This function will operate for addition of any datatype. Like, sum(2, 3) will give 5 and sum(2.5, 2.1) will give 4.6. A single function is doin that. We do not need to define two separate sum functions for int and float.

Types of Templates:

Templates are of two kinds in C++:
  • Function Templates
  • Class Templates

Function Templates:

As we have discussed that function template is a function that is used with different data types.

funcTemplate.cpp
#include <iostream>
using namespace std;

template <typename T>
void max(T &a, T &b) {
    if(a > b){
    	cout<<a<<endl;
	}
	
	else{
		cout<<b<<endl;
	}
	
}
int main() {
	int a = 10, b = 12;
	max(a, b);
	
	float c = 12.12, d = 34.21;
	max(c, d);
	
	char e = 'A', f = 'Z';
	max(e, f);
    return 0;
}

In this example,

  • We have made a template using template keyword and then write our type name.
  • After type name, we write "T" - which is our generic data type.
  • Then we have written our function simply but changed our data type everywhere to "T".
  • Now whenever we call our template function, the data type "T" will be treated as the data type of the arguments. In this way, we can call our function with any data type we want.

Class Templates:

Using class templates, we can define generic classes to work with different data types. Class templates are also defined using template keyword.

funcTemplate.cpp
#include <iostream>
using namespace std;

template <typename T1, typename T2>
class Pair {
	private:
    	T1 first;
    	T2 second;
	public:
    	Pair(T1 first, T2 second){
			this->first = first;
			this->second = second;
		}

    	T1 getFirst() const { 
			return first; 
		}
    	T2 getSecond() const {
		 return second; 
		}


};
int main() {
    Pair<int, double> myPair(42, 3.14);
    cout << "First value: "<<myPair.getFirst()<< ", "
     << "Second value: "<<myPair.getSecond();
    cout<<endl;

    Pair<string, char> pair("Hello", 'X');
    cout << "First value: "<<pair.getFirst()<< ", "
     << "Second value: "<<pair.getSecond();
    cout<<endl;

    
    return 0;
}

In this example,

  • We have made a class template using the "template" keyword and then write our type name.
  • Now we are using two parameters, we write "T1" as first type name and "T2" as second type name - which are our generic data types.
  • Then we have written our class simply but changed the data types.
  • In main function, after our class name, we specified the data types of arguments we are passing.