FUNCTION
TEMPLATES
Function templates are special
functions that can operate with generic types. This allows us to create
a function template whose functionality can be adapted to more than one type or
class without repeating the entire code for each type.
In C++ this can be achieved
using template parameters. A template parameter is a special kind of
parameter that can be used to pass a type as argument: just like regular
function parameters can be used to pass values to a function, template
parameters allow to pass also types to a function. These function templates can
use these parameters as if they were any other regular type.
Syntax:
The syntax for declaring function templates with
type parameters is:
template <class identifier> function_declaration;
For example, to create a template function that returns the greater one of two objects we could use:
template <class identifier> function_declaration;
For example, to create a template function that returns the greater one of two objects we could use:
1
2 3 4 |
template <class T>
T GetMax (T a, T b)
{
return (a>b?a:b);
}
|
Here we have created a template function with T as its template parameter. This template parameter represents a type that has not yet been specified, but that can be used in the template function as if it were a regular type. As you can see, the function template GetMax returns the greater of two parameters, whose types are not yet defined.
To use this function template we use the following
format for the function call:
function_name
<type> (parameters);
For example, to call GetMax to compare two integer
values of type int we can write:
1
2 |
int x,y;
GetMax <int> (x,y);
|
When the compiler encounters this call to a template function, it uses the template to automatically generate a function replacing each appearance of T by the type passed as the actual template parameter (int in this case) and then calls it. This process is automatically performed by the compiler and is invisible to the programmer.
Here is the entire example:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
// function template
#include <iostream>
using namespace std;
template <class T>
T GetMax (T a, T b)
{
T result;
result = (a>b)? a : b;
return (result);
}
int main ()
{
int i=5, j=6, k;
long l=10, m=5, n;
k=GetMax<int>(i,j); //or GetMax(i,j)
n=GetMax<long>(l,m); //or GetMax(l,m)
cout << k << endl;
cout << n << endl;
return 0;
}
|
|
Output:
6
10
In the example above we used the function template
GetMax() twice. The first time with arguments of type int and the second one
with arguments of type long. The compiler has instantiated and then called each
time the appropriate version of the function.
As you can see, the type T is used within the
GetMax() template function even to declare new objects of that type:
|
T result;
|
Therefore, result will be an object of the same type as the parameters a and b when the function template is instantiated with a specific type.
Since both i and j are of type int, and the
compiler can automatically find out that the template parameter can only be
int. This implicit method produces exactly the same result:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// function template II
#include <iostream>
using namespace std;
template <class T>
T GetMax (T a, T b)
{
return (a>b?a:b);
}
// main function
int main () {
int i=5, j=6, k;
long l=10, m=5, n;
k=GetMax(i,j);
n=GetMax(l,m);
cout << k << endl;
cout << n << endl;
return 0;
}
|
Output:
6
10
Notice how in this case, we called our function template GetMax() without explicitly specifying the type between angle-brackets <>. The compiler automatically determines what type is needed on each call.
Because our template function includes only one template parameter (class T) and the function template itself accepts two parameters, both of this T type, we cannot call our function template with two objects of different types as arguments:
Notice how in this case, we called our function template GetMax() without explicitly specifying the type between angle-brackets <>. The compiler automatically determines what type is needed on each call.
Because our template function includes only one template parameter (class T) and the function template itself accepts two parameters, both of this T type, we cannot call our function template with two objects of different types as arguments:
1
2 3 |
int i;
long l;
k = GetMax (i,l); // i, l are
two different types
|
This would not be correct, since our GetMax function template expects two arguments of the same type, and in this call we are passing objects of two different types.
We can also define function templates that accept more than one type parameter, simply by specifying more template parameters between the angle brackets. For example:
1
2 3 4
5
|
template <class T, class U> // two template parameters are used T, U
T GetMin (T a, U b)
{
return (a<b?a:b);
}
|
In this case, our function template GetMin() accepts two parameters of different types and returns an object of the same type as the first parameter (T) that is passed. For example, after that declaration we could call GetMin() with:
1
2 3 |
int i,j;
long l;
i = GetMin<int,long> (j,l);
|
or simply:
|
i = GetMin(j,l);
|
even though j and l have different types, since the compiler can determine the appropriate instantiation anyway.
No comments:
Post a Comment