According to the above quote, the default template-argument need to be implicitly instantiated, However at this point, T
is a template-parameter and the definition of such function template instantiate nothing(It's just a function template definition at this point). So, How does the quote interpret this?
The key is the difference between need of instantiation and when referenced. In the example from [temp.arg]/8, the default template argument for U
is instantiated because it is needed for the instantiation of S<bool>
, which unambiguously resolves to S<bool, int>
. In the OP's own example, instantiation of the instantiation-dependent default template argument for U
will only follow after overload resolution resolves void func(Test<T>)
as the best viable overload and thus instantiates it. Just inspecting candidate overloads as part of overload resolution, however, will not lead to instantiation of any of the candidates nor any of the function template candidates parameters that are, themselves, templates. It will, however, be referencing said template parameters as part of the overload resolution process (discarding non-viable candidates).
From [temp.deduct]/1 [emphasis mine]:
When a function template specialization is referenced, all of the template arguments shall have values. The values can be explicitly specified or, in some cases, be deduced from the use or obtained from default template-arguments. [...]
For the OP's particular example, the former (instantiation) only occurs after overload resolution has finished and a best viable overload has been instantiated (which in turn instantiates the class template function argument). The latter (a function/class template specialization being referenced to), however, applies also during overload resolution, even when discarding candidates that are either not viable or not the best viable match, candidates that will never lead to instantiations.
From [temp.deduct]/2 [emphasis mine]:
When an explicit template argument list is specified, the template arguments must be compatible with the template parameter list and must result in a valid function type as described below; otherwise type deduction fails. Specifically, the following steps are performed when evaluating an explicitly specified template argument list with respect to a given function template:
- (2.1) The specified template arguments must match the template parameters in kind (i.e., type, non-type, template). There must not be more arguments than there are parameters unless [...]
and from [temp.deduct]/6 [emphasis mine]:
At certain points in the template argument deduction process it is necessary to take a function type that makes use of template parameters and replace those template parameters with the corresponding template arguments. This is done at the beginning of template argument deduction when any explicitly specified template arguments are substituted into the function type, and again at the end of template argument deduction when any template arguments that were deduced or obtained from default arguments are substituted.
it is clear that as part of the "end of template argument deduction", any template arguments that have not been explicitly specified will be either deduced or obtained from default arguments and substituted into the candidate function before discarding or ranking it as a viable overload. This applies without any relation to instantiation, and only in the context of a given specialization (that may not yet or ever be instantiated) being referenced, as part of overload resolution.
Finally, from [temp.deduct.type]/3 [emphasis mine]:
A given type P
can be composed from a number of other types, templates, and non-type values:
- [...]
- (3.3) A type that is a specialization of a class template (e.g.,
A<int>
) includes the types, templates, and non-type values referenced by the template argument list of the specialization.
we note that as part of function template argument deduction for a function template parameter that is a specialization of a class template, the function template parameter type (used for deduction against an argument) includes the types referenced by the template argument list of the template parameter, meaning the particular class template specialization (function template argument) is referenced, so that, as per [temp.deduct]/1, it will go through template argument deduction and default-argument inspection for any of its template arguments that are not explicitly specified.