C++ Function Templates


C++ Function Templates: A Comprehensive Guide

In C++, templates are a powerful feature that allows you to create generic functions and classes. Function templates provide a way to write functions that can operate with different data types without being rewritten for each type. In this guide, we will explore how function templates work, how to use them, and some common use cases with sample code.


What is a C++ Function Template?

A function template allows you to define a function without specifying the exact type of data it will operate on. Instead, you define a placeholder type, and the compiler will automatically generate the correct function based on the type of argument passed to it during function calls.

Syntax of a Function Template:

template <typename T>
return_type function_name(parameter_list) {
    // Function body
}
  • template <typename T>: This is the function template declaration. The T is a placeholder for the data type that will be used when the function is called.
  • return_type: This specifies the return type of the function.
  • parameter_list: These are the parameters for the function, where you can use T as the data type for the parameters.

Benefits of Function Templates

  • Code Reusability: You don't need to write separate functions for each data type.
  • Type Safety: The compiler checks the type at compile time.
  • Flexibility: Function templates can work with any data type, making the code more flexible and maintainable.

Sample Code: C++ Function Template

Example 1: A Template Function for Swapping Two Values

Let's start with a simple example of a function template that swaps two values of any data type.

#include <iostream>
using namespace std;

// Function template to swap two values
template <typename T>
void swapValues(T &a, T &b) {
    T temp = a;
    a = b;
    b = temp;
}

int main() {
    int x = 5, y = 10;
    double p = 3.14, q = 6.28;
    
    // Swapping integers
    cout << "Before swap: x = " << x << ", y = " << y << endl;
    swapValues(x, y);  // Calling template function with int
    cout << "After swap: x = " << x << ", y = " << y << endl;
    
    // Swapping doubles
    cout << "Before swap: p = " << p << ", q = " << q << endl;
    swapValues(p, q);  // Calling template function with double
    cout << "After swap: p = " << p << ", q = " << q << endl;
    
    return 0;
}

Explanation:

  • The swapValues function template accepts two parameters of type T (which can be any data type) and swaps their values.
  • In the main function, we call the template function swapValues with both int and double types, demonstrating how it works with different data types.

Output:

Before swap: x = 5, y = 10
After swap: x = 10, y = 5
Before swap: p = 3.14, q = 6.28
After swap: p = 6.28, q = 3.14

Example 2: A Template Function for Finding the Maximum of Two Values

Let's create a template function that finds the maximum of two values.

#include <iostream>
using namespace std;

// Function template to find the maximum of two values
template <typename T>
T findMax(T a, T b) {
    return (a > b) ? a : b;
}

int main() {
    int x = 3, y = 7;
    double p = 3.5, q = 2.8;

    // Find the maximum of integers
    cout << "Maximum of " << x << " and " << y << " is " << findMax(x, y) << endl;
    
    // Find the maximum of doubles
    cout << "Maximum of " << p << " and " << q << " is " << findMax(p, q) << endl;
    
    return 0;
}

Explanation:

  • The findMax function template takes two parameters of the same type T and returns the maximum of the two.
  • The main function demonstrates calling this template function with both int and double.

Output:

Maximum of 3 and 7 is 7
Maximum of 3.5 and 2.8 is 3.5

Template Specialization

Sometimes, you may need a function template that behaves differently for certain types. This is where template specialization comes into play. You can define a specialized version of a template function for a specific data type.

Example: Specializing a Template for char Type

#include <iostream>
using namespace std;

// General template
template <typename T>
T print(T t) {
    cout << "General Template: " << t << endl;
    return t;
}

// Template specialization for char
template <>
char print<char>(char c) {
    cout << "Specialized Template for char: " << c << endl;
    return c;
}

int main() {
    int a = 10;
    char b = 'A';
    
    // Calling general template
    print(a);
    
    // Calling specialized template
    print(b);
    
    return 0;
}

Explanation:

  • The general template print works with any data type.
  • We have specialized this template for the char type, where the function prints a different message when dealing with characters.

Output:

General Template: 10
Specialized Template for char: A

Function Templates with Multiple Parameters

You can also create function templates with more than one parameter. For example, let’s write a function template that finds the smaller of two values of different types.

#include <iostream>
using namespace std;

// Function template for finding the smaller of two values
template <typename T, typename U>
auto findSmaller(T a, U b) -> decltype(a < b ? a : b) {
    return (a < b) ? a : b;
}

int main() {
    int x = 5;
    double y = 4.3;
    
    cout << "Smaller value is: " << findSmaller(x, y) << endl;

    return 0;
}

Explanation:

  • The findSmaller function template takes two parameters of different types T and U and returns the smaller of the two.
  • We use decltype to automatically deduce the return type based on the comparison of a and b.

Output:

Smaller value is: 4.3