C++ Function Templates
C++ Templates – Part 1
Forward: In this article, I show you how to write function templates in C++.
By: Chrysanthus Date Published: 24 Aug 2012
Introduction
Note: If you cannot see the code or if you think anything is missing (broken link, image absent), just contact me at forchatrans@yahoo.com. That is, contact me for the slightest problem you have about what you are reading.
Ordinary Function
Consider the following code:
#include <iostream>
using namespace std;
int myIFn(int anInt)
{
return anInt;
}
float myFFn(float aFlt)
{
return aFlt;
}
int main()
{
int theInt = myIFn(5);
cout << theInt; cout << "\n";
float theFlt = myFFn(4.2);
cout << theFlt;
return 0;
}
The ordinary functions myIFn() and myFFn() return the argument passed to them. myIFn() returns an Int, while myFFn() returns a float. For any ordinary function, the argument sent must be of the same object type as the parameter in the function parameter list. It is possible to have two or more functions in a code that do the same thing except for the fact that arguments and their types, passed to them, are different. In such functions all the statements in the function definition blocks are the same except for the arguments and their object types received into the function block. That is a waste. The above code illustrates this waste.
For the above problem, it is possible to have just one function and pass an argument of a different type, each time the function is called. Such a function is called a function template and there is a special way of producing it.
In the following code, we have one function that does what the above two functions do.
#include <iostream>
using namespace std;
template <class myType>
myType myFn(myType myID)
{
return myID;
}
int main()
{
int theInt = myFn<int>(5);
cout << theInt; cout << "\n";
float theFlt = myFn<float>(4.2);
cout << theFlt;
return 0;
}
The one function that replaces the two functions above, begins with the keyword, template. You have a space and then angle brackets. Inside the angle brackets you have the keyword, class, which you can consider here as meaning, name of type. You can also use the word, “typename” instead of “class”. After that you have a space and then the identifier (name) that will identify any object type you will use. This is a placeholder for any object type. There is no semicolon after the close angle bracket.
To call this function (in the main function block), you begin with the function name, then the type of argument you want to send in angle brackets and then the argument in parentheses. In the main function block above, the function was called with an int and then it was called again with a float. You can still call it with a char, bool, etc. In that way, different argument types will use the same function (template function).
Syntax for Function Template
In simple terms, the syntax for a function template is,
template <class T>
T functionName(Parameter Declarations)
{
//statements with template placeholders
}
where T is the generic type. A parameter declaration begins with T and then a space and then the identifier for an object. In simple terms, the syntax to call a function is,
functionName<T>(arguments)
Well, in calling the function, <T> is optional and can be omitted. So, the int function call statement, could have been made like this:
int theInt = myFn(5);
without, <int> .
The above function template has only one parameter. A function template can have several parameters. The following code has a function template with two parameters (and two arguments):
#include <iostream>
using namespace std;
template <class T>
T myFn(T ID1, T ID2)
{
return ID1 + ID2;
}
int main()
{
int theInt = myFn<int>(5, 6);
cout << theInt;
return 0;
}
The above code should be self-explanatory. The function has only one generic type. So, despite the fact that the function has two parameters, in the function call, only one <int> and not two of them (<int><int>) are used.
Different Argument Types
In the above example the arguments (several) are of the same type. You can have arguments of different types as in the following example:
#include <iostream>
using namespace std;
template <class T, class U>
U myFn(T ID1, U ID2)
{
return ID1 + ID2;
}
int main()
{
float theVal = myFn<int, float>(5, 4.3);
cout << theVal;
return 0;
}
The two arguments are of the int and float types. So we are talking about two generic types (T and U), here. In the template angle brackets expression (template parameter list), you have to indicate that you will use arguments of different types (T and U have been used for this). As you type the function you have to indicate the returned type (e.g. U above). The function has been called with an int for T and a float for U. In calling the function, we had to type the two argument types in angle brackets, <int, float>. If you omit, <int, float> in the function call, the code will still work.
Note: The angle brackets just before function definition, has the template parameter declarations; the angle brackets at function call, has template argument types.
All the parameters of the template function do not have to be generic types. You can also have specific parameter types. The following code illustrates this:
#include <iostream>
using namespace std;
template <class T, class U>
U myFn(T ID1, U ID2, bool B)
{
if (B == true)
{
return ID1 + ID2;
}
else
{
return ID1 - ID2;
}
}
int main()
{
float theVal = myFn(5, 4.3, true);
cout << theVal;
return 0;
}
The function will add an int to a float if the Boolean value is true, otherwise it would subtract the float from the int. The specific parameter above is not indicated in the angle brackets of the template parameter list. However, the parameter has to be declared in the parameter parentheses of the function. Note that in calling the function, the template argument list, <int, float, bool> has not been used, because of the specific argument (bool). In fact using it here, generates an error by the compiler.
Note: All type placeholders in the angle brackets of the template parameter list have to be used in the function definition. In the above case, T and U have been used in the function definition.
A function template is a function that can receive different argument types for the same identifier passed. It is like many functions combined in one. It is through the object type placeholders (e.g. T and U above) that you have generic object types. Above, T, is a generic object type, and, U, is another generic object type.
Function Template Prototype
A function has a prototype. A template function can also have a prototype. The prototype of the previous template above is,
template <class T, class U>
U myFn(T ID1, U ID2);
Or
template <class T, class U> U myFn(T ID1, U ID2);
Note the semicolon at the very end of the prototype. Read and try the following code, which illustrates the use of the prototype:
#include <iostream>
using namespace std;
template <class T, class U> U myFn(T ID1, U ID2);
template <class T, class U>
U myFn(T ID1, U ID2)
{
return ID1 + ID2;
}
int main()
{
float theVal = myFn<int, float>(5, 4.3);
cout << theVal;
return 0;
}
That is it for Function Templates. Let us take a break here and continue in the next part of the series, which is Class Templates.
Chrys
Related Courses
C++ CourseRelational Database and Sybase
Windows User Interface
Computer Programmer – A Jack of all Trade – Poem
NEXT