template
Suppose the program that contains those templates also contains the following code:
struct blot {int a; char b[10];};
blot ink = {25, "spots"};
...
recycle(&ink); // address of a structure
The recycle(&ink) call matches Template #1, with Type interpreted as blot *. The recycle(&ink) function call also matches Template #2, this time with Type being ink. This combination sends two implicit instantiations, recycle
Of these two template functions, recycle
The rules for finding the most specialized template are called the
A Partial Ordering Rules Example
Let’s examine a complete program that uses the partial ordering rules for identifying which template definition to use. Listing 8.14 has two template definitions for displaying the contents of an array. The first definition (Template A) assumes that the array that is passed as an argument contains the data to be displayed. The second definition (Template B) assumes that the array elements are pointers to the data to be displayed.
Listing 8.14. tempover.cpp
// tempover.cpp -- template overloading
#include
template
void ShowArray(T arr[], int n);
template
void ShowArray(T * arr[], int n);
struct debts
{
char name[50];
double amount;
};
int main()
{
using namespace std;
int things[6] = {13, 31, 103, 301, 310, 130};
struct debts mr_E[3] =
{
{"Ima Wolfe", 2400.0},
{"Ura Foxe", 1300.0},
{"Iby Stout", 1800.0}
};
double * pd[3];
// set pointers to the amount members of the structures in mr_E
for (int i = 0; i < 3; i++)
pd[i] = &mr_E[i].amount;
cout << "Listing Mr. E's counts of things:\n";
// things is an array of int
ShowArray(things, 6); // uses template A
cout << "Listing Mr. E's debts:\n";
// pd is an array of pointers to double
ShowArray(pd, 3); // uses template B (more specialized)
return 0;
}
template
void ShowArray(T arr[], int n)
{
using namespace std;
cout << "template A\n";
for (int i = 0; i < n; i++)
cout << arr[i] << ' ';
cout << endl;
}
template
void ShowArray(T * arr[], int n)
{
using namespace std;
cout << "template B\n";
for (int i = 0; i < n; i++)
cout << *arr[i] << ' ';
cout << endl;
}
Consider this function call:
ShowArray(things, 6);
The identifier things is the name of an array of int, so it matches the following template with T taken to be type int:
template
void ShowArray(T arr[], int n);
Next, consider this function call:
ShowArray(pd, 3);
Here, pd is the name of an array of double *. This could be matched by Template A:
template
void ShowArray(T arr[], int n);
Here, T would be taken to be type double *. In this case, the template function would display the contents of the pd array: three addresses. The function call could also be matched by Template B:
template
void ShowArray(T * arr[], int n);
In this case, T is type double, and the function displays the dereferenced elements *arr[i]—that is, the double values pointed to by the array contents. Of the two templates, Template B is the more specialized because it makes the specific assumption that the array contents are pointers, so it is the template that gets used.
Here’s the output of the program in Listing 8.14:
Listing Mr. E's counts of things:
template A
13 31 103 301 310 130
Listing Mr. E's debts:
template B
2400 1300 1800
If you remove Template B from the program, the compiler then uses Template A for listing the contents of pd, so it lists the addresses instead of the values. Try it and see.