Function Templates

Recall the print() function we saw in the previous example:

void print(int arr[], int length) {
	for (int i = 0; i < length; i++) {
		cout << arr[i] << " ";
	}
	cout << endl;
}
void print(char arr[], int length) {
	for (int i = 0; i < length; i++) {
		cout << arr[i] << " ";
	}
	cout << endl;
}
void print(double arr[], int length) {
	for (int i = 0; i < length; i++) {
		cout << arr[i] << " ";
	}
	cout << endl;
}

The only thing that differentiates this function is the argument type. When programming, it's not uncommon to have functions like this — the same computation, but different arguments. In these situations, it's best to use a function template. We can think of a function template as simply a more general, or abstract form of the function. We can reduce the functions above into a single function:

template<class T>
void print(T arr[], int length) {
	for (int i = 0; i < length; i++) {
		cout << arr[i] << " ";
	}
	cout << endl;
}

The T in the code above essentially acts like a placeholder. C++ will replace the T with the appropriate data type. This results in print() becoming a generic function. Applying this feature, our code begins to look cleaner, while keeping the added functionality:

#include <iostream>
using namespace std;
#define SIZEOF(a) sizeof(a)/sizeof(*a)

template<class T>
void print(T arr[], int length);

int main() {
	int intArr[]{1, 2, 3, 4};
	char charArr[]{'a', 'b', 'c', 'd'};
	double doubleArr[]{1.2, 2.9, 3.1, 3.10};

	print(intArr, SIZEOF(intArr));
	print(charArr, SIZEOF(charArr));
	print(doubleArr, SIZEOF(doubleArr));
	return 0;
}

template<class T>
void print(T arr[], int length) {
	for (int i = 0; i < length; i++) {
		cout << arr[i] << " ";
	}
	cout << endl;
}
1 2 3 4
a b c d
1.2 2.9 3.1 3.1

Notice that because we must include function signatures, the template declaration must appear both before the function signature and before the function's definition. Of course, we can avoid this by simply placing our function definition before main():

#include <iostream>
using namespace std;
#define SIZEOF(a) sizeof(a)/sizeof(*a)

template <class T>
void print(T arr[], int length) {
	for (int i = 0; i < length; i++) {
		cout << arr[i] << " ";
	}
	cout << endl;
}

int main() {
	int intArr[]{1, 2, 3, 4};
	char charArr[]{'a', 'b', 'c', 'd'};
	double doubleArr[]{1.2, 2.9, 3.1, 3.10};

	print(intArr, SIZEOF(intArr));
	print(charArr, SIZEOF(charArr));
	print(doubleArr, SIZEOF(doubleArr));
	return 0;
}