11.1.1.  Function Templates

[ fromfile: templates.xml id: functiontemplates ]

Function templates create type-checked functions that all work on the same pattern. Example 11.1 defines a template function that raises a value of type T to the power exp by repeatedly applying the operator*=.

Example 11.1. src/templates/template-demo.cpp

[ . . . . ]

template <class T> T power (T a, int exp) {
  T ans = a;
  while (--exp > 0) {
    ans *= a;
  }
  return (ans);
}

<include src="src/templates/template-demo.cpp" mode="cpp" href="src/templates/template-demo.cpp" id="templatepower" segid="power"/>


Once again, the compiler must do extra work to provide this convenient feature of C++. The compiler scans our code and generates as many different function bodies as necessary, based on the argument types supplied in the function calls, so that all calls can be resolved at compile-time, as shown in Example 11.2. Even though the word class is in the template parameter, T can be a class or a primitive type. The only limitation on the type T is that it must be a type for which the operator*= is defined.

Example 11.2. src/templates/template-demo.cpp

[ . . . . ]


int main() {
  Complex z(3,4), z1;
  Fraction f(5,6), f1;
  int n(19);
  z1 = power(z,3);              1
  f1 = power(f,4);              2
  z1 = power<Complex>(n, 4);    3
  z1 = power(n,5);              4

}

1

First instantiation: T is Complex.

2

Second instantiation: T is Fraction.

3

Supply an explicit template parameter if the actual argument is not "specific" enough. This results in a call to a function that was already instantiated.

4

Which version gets called?

<include src="src/templates/template-demo.cpp" mode="cpp" href="src/templates/template-demo.cpp" id="templatedemocpp" segid="main"/>


Each time the compiler sees a template function used for the first time with a specific combination of parameter types, we say the template is instantiated. Subsequent uses of of power(Complex, int) or power(Fraction, int) translate into ordinary function calls.

[Note]Note

One important difference between overloaded functions and multiple specializations of the same template function is that overloaded functions must return the same type. Example 11.2 shows different versions of the template power() function with different return types. Overloaded functions must all have the same return type.