Skip to content

Template Functions

Template functions allow you to write code that works with multiple data types without having to rewrite the same logic repeatedly. They’ll remind you of Generics from Java in CSCE146. They let you define a single function, and the compiler will generate type-specific versions of that function for the data types you use.

To define a template function, you use the template keyword followed by a template parameter list enclosed in angle brackets. Each template parameter is introduced by typename (or class) to indicate that it’s a type parameter. For example:

template <typename T>
T Add(T a, T b) {
return a + b;
}

From the example:

  • template<typename T> indicates that T is a placeholder type, which the compiler will deduce from the arguments you pass.

  • Add is defined once, but can be used with any type that supports the + operator (e.g., int, double, or even user-defined classes if they implement the necessary operator).

int result1 = Add(1, 2);
double result2 = Add(1.5, 2.5);

Good candidates for template functions include common array-based algorithms and utility functions where the logic doesn’t depend on a specific data type. For instance, you can create a template function that prints the contents of an array, or one that reverses an array, making them work seamlessly with arrays of int, double, char, or any other type you need—without rewriting the entire function.

  1. Create Driver

    Create your driver file, import what you need, and declare your template functions. Unfortunately, we have to declare template <typename T> for each function:

    driver.cc
    // Copyright 2024 CSCE240
    #include <iostream>
    using std::cout;
    using std::endl;
    template <typename T>
    void Print(const T*, int);
    template <typename T>
    void Reverse(T*, int);
    template <typename T>
    void Swap(T*, int, int);
  2. Define Implementation

    Under the main function, write the implementation for each function. Again, we have to use template <typename T> for each function.

    The first function is our Print function:

    driver.cc
    template <typename T>
    void Print(const T* array, int size) {
    for (int i = 0; i < size; ++i) {
    cout << array[i] << " ";
    }
    cout << endl;
    }

    The next function is the utility function for swapping elements in an array:

    driver.cc
    template <typename T>
    void Swap(T* array, int i, int j) {
    T temp = array[i];
    array[i] = array[j];
    array[j] = temp;
    }

    The final function to define is Reverse which will change the position of all elements in an array (except the middle element in arrays which are oddly sized):

    driver.cc
    template <typename T>
    void Reverse(T* array, int size) {
    int i = 0, j = size - 1;
    while (i < j) {
    Swap(array, i, j);
    ++i, --j;
    }
    }
  3. Test Functions

    Now its time to see if we’ve defined our functions correctly:

    driver.cc
    int main() {
    const int kSize = 5;
    char char_test[kSize] = "csce";
    int int_test[kSize] = {1, 2, 3, 4, 5};
    double dub_test[kSize] = {1.1, 2.1, 3.1, 4.1, 5.1};
    Reverse(char_test, kSize - 1);
    Reverse(int_test, kSize);
    Reverse(dub_test, kSize);
    Print(char_test, kSize);
    Print(int_test, kSize);
    Print(dub_test, kSize);
    return 0;
    }