Templates can be used with functions and with classes.
Templates are used because rewriting the same code over and over to handle different types is awful.
Suppose we want to write a function that returns the absolute value of two numbers.
We can write an absolute value function as a template, so it will work with any numerical type.
#include <iostream> using namespace std; template <class T> T tAbs(T num) { return (num < 0) ? -num : num; } int main() { long long lOne = -19191138L; long long lTwo = -20012010L; double dOne = 19.99; double dTwo = -8.32; std::cout << lOne << " " << tAbs(lOne) << std::endl; std::cout << dTwo << " " << tAbs(dTwo) << std::endl; return 0; }
Function templates represent the data type used by the function not as a specific type, such as int, but by an identifier that can stand in for any type. The template keyword signifies to the compiler that we’re about to define a function template. The variable following the keyword class is called the template argument.
The compiler decides how to compile the function based entirely on the data type used in the function call’s argument.
Le’ts look at a function template with two arguments.
#include <iostream> using namespace std; //function returns index of item, or value < 0 if not found template <class theType> int find(theType arrayParam[], theType value, int size) { for (int j = 0; j < size; j++) { if (arrayParam[j] == value) { return j; } } return -1; } //outputs value if index >= 0; template <class theType> void printIt(theType arrayParam[], int indexParam) { if (indexParam >= 0) { std::cout << "At index " << indexParam << " " << arrayParam[indexParam] << std::endl; } else { std::cout << "Value not found." << std::endl; } } int main() { char chrArr[] = { 'h', 'U', 't', 'i', 'D', 'v', 's' }; int intArr[] = { 42, 1138, 73, 47, 8086, 1999, 3 }; int iLength = 7; int iIndex = -1; iIndex = find(chrArr, 'v', iLength); printIt(chrArr, iIndex); printIt(chrArr, find(intArr, 2001, iLength)); return 0; }
We can use more than one template argument in a function template.
#include <iostream> using namespace std; //outputs value if index >= 0; template <class TOne, class TTwo> void printBoth(TOne paramOne, TTwo paramTwo){ std::cout << "Parameter one is " << paramOne << std::endl; std::cout << "Parameter two is " << paramTwo << std::endl; } int main() { printBoth('c', 1982); printBoth("If mice could swim, they would float with the tide and play with the fish down by the seaside. The cats on the shore would quickly agree.", 7); printBoth(19.99, 'X'); return 0; }
It is not always easy to know if we can instantiate a template function for a particular data type. One thing we can do is check if the operators used in the function can work on the data type.