Note that just the signatures and not the return types are considered. Two of these candidates (#4 and #7), however, are not viable because an integral type cannot be converted implicitly (that is, without an explicit type cast) to a pointer type. The remaining template is viable because it can be used to generate a specialization, with T taken as type char. That leaves five viable functions, each of which could be used if it were the only function declared.
Next, the compiler has to determine which of the viable functions is best. It looks at the conversion required to make the function call argument match the viable candidate’s argument. In general, the ranking from best to worst is this:
1. Exact match, with regular functions outranking templates
2. Conversion by promotion (for example, the automatic conversions of char and short to int and of float to double)
3. Conversion by standard conversion (for example, converting int to char or long to double)
4. User-defined conversions, such as those defined in class declarations
For example, Function #1 is better than Function #2 because char-to-int is a promotion (refer to Chapter 3, “Dealing with Data”), whereas char-to-float is a standard conversion (refer to Chapter 3). Functions #3, #5, and #6 are better than either #1 or #2 because they are exact matches. Both #3 and #5 are better than #6 because #6 is a template. This analysis raises a couple questions. What is an exact match? And what happens if you get two of them, such as #3 and #5? Usually, as is the case with this example, two exact matches are an error; but a couple special cases are exceptions to this rule. Clearly, we need to investigate the matter further!
Exact Matches and Best Matches
C++ allows some “trivial conversions” when making an exact match. Table 8.1 lists them, with
Table 8.1. Trivial Conversions Allowed for an Exact Match
Suppose you have the following function code:
struct blot {int a; char b[10];};
blot ink = {25, "spots"};
...
recycle(ink);
In that case, all the following prototypes would be exact matches:
void recycle(blot); // #1 blot-to-blot
void recycle(const blot); // #2 blot-to-(const blot)
void recycle(blot &); // #3 blot-to-(blot &)
void recycle(const blot &); // #4 blot-to-(const blot &)
As you might expect, the result of having several matching prototypes is that the compiler cannot complete the overload resolution process. There is no best viable function, and the compiler generates an error message, probably using words such as
However, sometimes there can be overload resolution even if two functions are an exact match. First, pointers and references to non-const data are preferentially matched to non-const pointer and reference parameters. That is, if only Functions #3 and #4 were available in the recycle() example, #3 would be chosen because ink wasn’t declared as const. However, this discrimination between const and non-const applies just to data referred to by pointers and references. That is, if only #1 and #2 were available, you would get an ambiguity error.
Another case in which one exact match is better than another is when one function is a non template function and the other isn’t. In that case, the non template is considered better than a template, including explicit specializations.
If you wind up with two exact matches that both happen to be template functions, the template function that is the more specialized, if either, is the better function. That means, for example, that an explicit specialization is chosen over one generated implicitly from the template pattern:
struct blot {int a; char b[10];};
template
template <> void recycle
...
blot ink = {25, "spots"};
...
recycle(ink); // use specialization
The term
template