Templates

The min function

  1. A set of functions in main.C that should be written as template function. The C++ Standard library already has a function named min whose full name is std::min because it belongs to the standard namespace std. The full name of my min functions is ::min, because they do not belong to any namespace. I had to write ::min to make sure I was calling my own min functions, not the one in the standard library.

    To get the expression b < a to compile when b and a are of data type const date&, I had to define the functions operator< or operator int for class date.

    	if (b < a) {       //if operator<(b, a) {
    
    	if (b < a) {       //if (b.operator int() < a.operator int()) {
    
    1. date.h: a very simple class date, just enough to make the main function work.
    2. date.C
    3. main.C
    c++ main.C date.C
    
    10
    2.71
    5/1/2025
    goodbye
    
  2. Declare and define a function template in main.C that will work for every data type except const char *.

    The first three calls to min in the main function create three instantiations of the function template. In the three instantiations, the computer deduces that the T should be changed to int, double, double, const date& respectively. (An instantiation is also called an implicit specialization.)

    The T is called a template argument. As usual, the a and b are called function arguments. And the 10 and 20 are the actual function arguments.

    1. date.h: exactly the same class date as in the previous example.
    2. date.C
    3. main.C: exactly the same main function as in the previous example, but the rest of main.C is different.
    c++ main.C date.C
    
    10
    2.71
    5/1/2025
    goodbye
    
  3. Combine the function declarations and definitions in main.C .
    1. date.h: exactly the same class date as in the previous example.
    2. date.C
    3. main.C: exactly the same main function as in the previous example, but the rest of main.C is different.
    c++ main.C date.C
    
    10
    2.71
    5/1/2025
    goodbye
    
  4. Move the function declarations and definitions to a .h (header) file.
    1. min.h contains the declarations and definitions of the min template function. See the important comment about the data type T.
    2. date.h: exactly the same class date as in the previous example.
    3. date.C
    4. main.C: exactly the same main function as in the previous example, but the rest of main.C is different.
    c++ main.C date.C
    
    10
    2.71
    5/1/2025
    goodbye
    
    See this min.h for a better version that passes function arguments of type T by reference, i.e., as a const T&.
    Ths shows that the data type of a function argument can be more than just a plain unadorned T.
  5. The min in the C++ Standard Library does not know that the data type const char * probably needs to be handled differently.
    1. date.h: exactly the same class date as in the previous example.
    2. date.C
    3. main.C calls the min function in the C++ Standard Library.

More than one template argument: T1 and T2

  1. Each print function has two arguments, which may be of different data types.
    1. date.h: exactly the same class date as in the previous example.
    2. date.C
    3. main.C
    c++ main.C date.C
    
    10 20
    3.14 5/1/2025
    A hello
    
  2. A template function can have more than one template argument.
    1. print.h contains the template
    2. date.h: exactly the same class date as in the previous example.
    3. date.C
    4. main.C
    c++ main.C date.C
    
    10 20
    3.14 5/1/2025
    A hello
    

A local variable of type T

  1. Three different swap functions:
    1. date.h: exactly the same class date as in the previous example.
    2. date.C
    3. main.C
    c++ main.C date.C
    
    i = 20, j = 10
    d = 2.71, e = 3.14
    today = 5/2/2025, tomorrow = 5/1/2025
    
  2. A template function containing a local variable of type const T:
    1. date.h: exactly the same class date as in the previous example.
    2. date.C
    3. swap.h contains the template
    4. main.C
    c++ main.C date.C
    
    i = 20, j = 10
    d = 2.71, e = 3.14
    today = 5/2/2025, tomorrow = 5/1/2025
    
    #include <algorithm> for the C++ Standard Library swap.

An explicit template argument

  1. The following call to our min template will not compile, because our min template requires two actual arguments of the same data type.
    1. min.h
    2. main.C
    c++ main.C
    
    main.C: In function ‘int main()’:
    main.C:14:22: error: no matching function for call to ‘min(int&, double&)’
       14 |         cout << ::min(i, d) << "\n";   //won’t compile
          |                 ~~~~~^~~~~~
    

A template class

  1. A class point with double data members:
    1. point.h: member functions and friends, inline and not inline
    2. point.C
    3. main.C
    c++ main.C point.C
    
    (3, 4)
    5
    
  2. The same class point with float data members:
    1. point.h: member functions and friends, inline and not inline
    2. point.C
    3. main.C
    c++ main.C point.C
    
    (3, 4)
    5
    
  3. A template class point. There is no more point.C file.
    1. point.h: member functions and friends, inline and not inline
    2. main.C
    c++ main.C
    
    (3, 4)
    5
    

A template class with a static member function

  1. Class counted is not a template class. It has a static member function named count which receives no invisible argument.
    1. counted.h
    2. counted.C
    3. main.C
    c++ main.C counted.C
    
    3
    
  2. Class numeric_limits is a template class with two static member functions, min and max.
    1. main.C
    c++ main.C
    
    short
                  -32768
                   32767
    
    int
             -2147483648
              2147483647
    
    long
    -9223372036854775808
     9223372036854775807
    
    We will never create any object of classes numeric_limits<int>, numeric_limits<long>, etc. The only purpose of these classes is to give us information about the data types int, long, etc. Other examples of classes that give us information about other data types are char_traits and iterator_traits.

All the Standard Library container classes are template classes.

  1. Class vector is a template class. Ditto for classes list and set.
    1. main.C
    c++ main.C
    
    10
    20
    30
    
    10.5
    20.5
    30.5
    
  2. Class map is a template class with two template arguments.
    1. map.C
    c++ map.C
    

A numeric template argument

  1. There are two types of zipcodes: 5 digits or 9 digits.
    1. zipcode.h
    2. main.C
    c++ main.C
    
    10458
    104581234
    

Templates and Inheritance

    We used to say typedef, but now we say using.
    1. using.C
    c++ using.C
    
    10
    20
    30
    
  1. Multiple inheritance from a virtual base class. Each grandchild (wolf, rabbit, boulder, landmine) contains only one copy of the grandparent (wabbit).
    1. wabbit.h: grandparent class
    2. wabbit.C

    3. immobile.h: three motion classes, with the keyword virtual
    4. randomly.h
    5. manual.h

    6. herbivore.h: three rank-in-the-food-chain classes, with the keyword virtual
    7. carnivore.h
    8. inert.h

    9. wolf.h: four grandchild classes. These header files #included by main.C.
    10. rabbit.h
    11. boulder.h
    12. landmine.h

    13. main.C: the main function
    14. term.h
    15. term.c
    16. terminal.h
    17. terminal.C
    cc -DUNIX= -c term.c
    ls -l term.o
    
    c++ main.C wabbit.C terminal.C term.o -lcurses
    ls -l a.out
    
    ./a.out
    
    Note that the grandchild classes wolf, rabbit, boulder, landmine are now identical, except for the names of the two parent classes of each grandchild, and the character that is the grandchild’s name on the screen. We can therefore write all the grandchild classes as a single template class.
  2. Remove the four nearly identical grandchild classes wolf, rabbit, boulder, landmine from the game. Simply do not include any of their header files wolf.h, rabbit.h, boulder.h, landmine.h in main.C. Instead, have main.C #include the following header file grandchild.h.
    1. grandchild.h
    Can main.C also create boulder and landmine objects? With the motion and rank classes we already have, we could easily create 3 × 3 = 9 classes of grandchildren.
    cc -DUNIX= -c term.c
    ls -l term.o
    
    c++ main.C wabbit.C terminal.C term.o -lcurses
    ls -l a.out
    
    ./a.out