When we initialize or assign a function pointer (§ 6.7, p. 247) from a function template, the compiler uses the type of the pointer to deduce the template argument(s).
As an example, assume we have a function pointer that points to a function returning an int
that takes two parameters, each of which is a reference to a const int
. We can use that pointer to point to an instantiation of compare
:
template <typename T> int compare(const T&, const T&);
// pf1 points to the instantiation int compare(const int&, const int&)
int (*pf1)(const int&, const int&) = compare;
The type of the parameters in pf1
determines the type of the template argument for T
. The template argument for T
is int
. The pointer pf1
points to the instantiation of compare
with T
bound to int
. It is an error if the template arguments cannot be determined from the function pointer type:
// overloaded versions of func; each takes a different function pointer type
void func(int(*)(const string&, const string&));
void func(int(*)(const int&, const int&));
func(compare); // error: which instantiation of compare?
The problem is that by looking at the type of func
’s parameter, it is not possible to determine a unique type for the template argument. The call to func
could instantiate the version of compare
that takes int
s or the version that takes string
s. Because it is not possible to identify a unique instantiation for the argument to func
, this call won’t compile.
We can disambiguate the call to func
by using explicit template arguments:
// ok: explicitly specify which version of compare to instantiate
func(compare<int>); // passing compare(const int&, const int&)
This expression calls the version of func
that takes a function pointer with two const int&
parameters.