Function Templates In C++


 

Function templates in C++

Templates are of two types.

1) Function Templates.


In this article we will study about function templates.

Why Function Templates

Function templates are a simple and powerful feature of C++. They are a form of generic programming. They are generic because we don't need to specify the return type of the function and the data types of the variables and parameters used in the function at the time of defining it. We can use one function template for different data types.

Take a look at the following code.

// defining a function "add" which takes 2 integer parameters
// and returns their sum
int add(int var1, int var2) {        
	return  var1 + var2;
}

// defining a function with the same name "add" which takes
// two double parameters and returns their sum
double add(double var1, double var2) {
	return var1 + var2;
}

In the above code, we see function overloading (multiple functions with same name but with different arguments). Except the function return type and parameter data type everything is same. 

Both the functions perform the same tasks i.e. adding values of two parameters except that the first function adds two integers and the second function adds two doubles.

In this situation we can use templates instead.

Creating a function template

// defining a function template
template<typename T>       // template takes one parameter for data type
T add(T var1, T var2) {    // function take two parameters and
	return var1 + var2;    // returns their sum
}

In the above code we created a function template. It starts with the keyword template and then in the angle brackets, another keyword typename (alias word for typename is class) and then a "placeholder" in which we have written T. T indicates the data type. You can write anything at the place of T. Here we have only one template parameter T.(we will see a template with multiple template parameters down in this article.

template<typename T>       // template takes one parameter for data type

As you can see on the next line, the return type of the function and the data type of its parameters is THere T can be any data type. T is a placeholder for the data type which is either deduced by the compiler from the arguments passed or is specified by the user at the time of calling this function.

We use the above template in the example below.

 1 
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<iostream>
using namespace std;

// defining a function template
template <typename T>
T add(T var1, T var2) {
	return var1 + var2;
}


int main() {
	
	int int1 = 3, int2 = 5;         // defining two integers
	cout << add<int>(int1, int2) << endl; // specifying data type while calling the function
	cout << add(int1, int2) << endl;      // data type deduced by the compiler

	double dou1 = 3.9, dou2 = 4.5;   // defining 2 doubles
	cout << add<double>(dou1, dou2) << endl;   // specifying data type while calling the function
	cout << add(dou1, dou2) << endl;        // data type deduced by the compiler

	return 0;
}

In the above example, from line 5, we create the function template. As said the return type of the function and the data type of the parameters of the function, which will be decided when we call the function are indicated by T.

On line 13, we defined two integer variables and on line 14, we print the result of the call to the function by passing the two integers.

cout << add<int>(int1, int2) << endl; // specifying data type while calling the function

Here we explicitly specify the data type (<int>) in the angular brackets while calling the function. This means that all the Ts in the function template are replaced by int

And on line 15, again we print the result of the call to the function by passing the two integers but this time we do not specify the data type, hence it is deduced by the compiler from the arguments provided.

cout << add(int1, int2) << endl;      // data type deduced by the compiler

Then on line 17, we defined two double variables, and on line 18, 

cout << add<double>(dou1, dou2) << endl;   // specifying data type while calling the function

We specified the data type (<double>), hence all the Ts in the function will be replaced by double when we call that function.

And on line 19, we do not specify the data type, hence it is deduced by the compiler from the arguments provided.

Here in this function both the parameters passed to the function must be of the same type.

In the above function template, we passed only one parameter T for data type, we can pass multiple parameters.

Function template with multiple template parameters

In the following example,

// defining a function template with multiple parameters for data types
template <typename T, typename U>
U add(T var1, U var2) {           // return type is U
	return var1 + var2;
}

the function template has two template parameters and on the next line, the function takes two parameters of two different data types and returns their sum.

Note that in the above code, the return type of the function and the data type of the second parameter is same. We executed the above function template in the below code.

 1 
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include<iostream>
using namespace std;

// defining a function template with multiple parameters for data types
template <typename T, typename U>
U add(T var1, U var2) {           // return type is U
	return var1 + var2;
}

int main() {
	// defining one integer and one double
	int int1 = 4;
	double dou1 = 3.8;

	// specifying both data types
	cout << add<int, double>(int1, dou1) << endl;
	// data type deduced by the compiler
	cout << add(int1, dou1) << endl;

	return 0;
}

In the program above, from line 5, we create the function template.

On line 12 and 13, we define an integer and a double variable respectively.

On line 16,

cout << add<int, double>(int1, dou1) << endl;

We call the function by passing the integer and double variable as arguments and explicitly specifying the data types (<int, double>). Here we have to specify both the data types separated by a comma in the angular brackets.

On line 18, we do not specify the data types hence the compiler will deduce the data types from the arguments passed.

So in this way we can use one function template for different data types.

Comments