Learn C++ - C++ Function Templates






A function template is a generic function description.

It defines a function with a generic type.

Later a specific type, such as int or double, can be substituted.

By passing a type as a parameter to a template, the compiler generates a function for that particular type.

Because types are represented by parameters, the template feature is referred to as parameterized types.

Function templates enable you to define a function in terms of some arbitrary type.

For example, you can set up a swapping template like this:

template <typename AnyType> 
void Swap(AnyType &a, AnyType &b) 
{ 
     AnyType temp; 
     temp = a; 
     a = b; 
     b = temp; 
} 

The first line sets up a template and you're naming the arbitrary type AnyType.

The keywords template and typename are obligatory, except that you can use the keyword class instead of typename.

The type name, AnyType, is your choice, as long as you follow the usual C++ naming rules.

Many programmers use simple names such as T.

The rest of the code describes the algorithm for swapping two values of type AnyType.





Example

The following code uses T instead of AnyType as the type parameter.


#include <iostream>
using namespace std;
/*from  ww  w.  ja v a  2 s. co  m*/
// function template prototype
template <typename T>  // or class T
void Swap(T &a, T &b);

int main(){
    int i = 10;
    int j = 20;
    cout << "i, j = " << i << ", " << j << ".\n";
    Swap(i,j);  // generates void Swap(int &, int &)
    cout << "Now i, j = " << i << ", " << j << ".\n";

    double x = 2.5;
    double y = 8.7;
    cout << "x, y = " << x << ", " << y << ".\n";
    Swap(x,y);  // generates void Swap(double &, double &)
    cout << "Now x, y = " << x << ", " << y << ".\n";
    return 0;
}

// function template definition
template <typename T>  // or class T
void Swap(T &a, T &b)
{
    T temp;   // temp a variable of type T
    temp = a;
    a = b;
    b = temp; 
}

The code above generates the following result.





Example 2


/* ww w  .  j  a  v a  2 s  .  c om*/
  #include <iostream> 
  using namespace std; 

  // Definition of function template maximum. 
  template < typename T >         // or template< typename T > 
  T maximum( T value1, T value2, T value3 ) 
  { 
      T maximumValue = value1; // assume value1 is maximum 

      // determine whether value2 is greater than maximumValue 
      if ( value2 > maximumValue ) 
          maximumValue = value2; 

      // determine whether value3 is greater than maximumValue 
      if ( value3 > maximumValue ) 
          maximumValue = value3; 

      return maximumValue ; 
  } // end function template maximum 

  int main() 
  { 
     // demonstrate maximum with int values 
     int int1, int2, int3; 

     cout << "Input three integer values: "; 
     cin >> int1 >> int2 >> int3; 

     // invoke int version of maximum 
     cout << "The maximum integer value is: " 
         << maximum( int1, int2, int3 ); 

     // demonstrate maximum with double values 
     double double1, double2, double3; 

     cout << "\n\nInput three double values: "; 
     cin >> double1 >> double2 >> double3; 

     // invoke double version of maximum 
     cout << "The maximum double value is: " 
         << maximum( double1, double2, double3 ); 

     // demonstrate maximum with char values 
     char char1, char2, char3; 

     cout << "\n\nInput three characters: "; 
     cin >> char1 >> char2 >> char3; 

     // invoke char version of maximum 
     cout << "The maximum character value is: " 
         << maximum( char1, char2, char3 ) << endl; 
  }

The code above generates the following result.

Overloaded Templates

You use templates when you need functions that apply the same algorithm to a variety of types.

You can overload template definitions,just as you overload regular function definitions.

Overloaded templates need distinct function signatures.


#include <iostream>
using namespace std;
template <typename T>     // original template
void Swap(T &a, T &b);
/*from ww  w.  j  av  a2s  .  c  om*/
template <typename T>     // new template
void Swap(T *a, T *b, int n);

void Show(int a[]);
const int Lim = 8;
int main(){
    
    int i = 10, j = 20;
    cout << "i, j = " << i << ", " << j << ".\n";
    Swap(i,j);              // matches original template
    cout << "Now i, j = " << i << ", " << j << ".\n";

    int d1[Lim] = {0,7,2,4};
    int d2[Lim] = {1,7,2,0};

    Show(d1); 
    Show(d2);
    Swap(d1,d2,Lim);        // matches new template
    Show(d1);
    Show(d2);
    return 0;
}

template <typename T>
void Swap(T &a, T &b) {
    T temp;
    temp = a;
    a = b;
    b = temp;
}

template <typename T>
void Swap(T a[], T b[], int n){
    T temp;
    for (int i = 0; i < n; i++)    {
        temp = a[i];
        a[i] = b[i];
        b[i] = temp;
    }
}

void Show(int a[]){
    cout << a[0] << a[1] << "/";
    cout << a[2] << a[3] << "/";
    for (int i = 4; i < Lim; i++)
        cout << a[i];
    cout << endl;
}

The code above generates the following result.