The general rule for implicit instantiation of class templates is as follows
[temp.inst]
2 Unless a class template specialization is a declared specialization, the class template specialization is implicitly instantiated when the specialization is referenced in a context that requires a completely-defined object type or when the completeness of the class type affects the semantics of the program. [...]
That in conjunction with this requirement about functions:
[dcl.fct.def.general] (emphasis mine)
2 In a function-definition, either void declarator ; or declarator ; shall be a well-formed function declaration as described in [dcl.fct]. A function shall be defined only in namespace or class scope. The type of a parameter or the return type for a function definition shall not be a (possibly cv-qualified) class type that is incomplete or abstract within the function body unless the function is deleted ([dcl.fct.def.delete]).
Tells us all we need to know to examine your program. Functions declarations don't require the class type to be complete. So...
Pow<double>
instantiated here?
No. This is a function declaration that is not a definition. It does not require a complete class type for a parameter. Pow<double>
is not implicitly instantiated.
Pow<int>
instantiated here?
Yes. This is a function definition, and so an instantiation is required.
Pow<int> pi;
// instantiated here?
Was already instantiated due to the function.
So when exactly the template is instantiated?
Strictly when required in a way that affects the semantics of the program.
So is Pow<int>
instantiated when func(Pow<int>)
is declared?
When func(Pow<int>)
is defined.
If I didn't use Pow<int>
in main()
then has it been instantiated because of its usage in func
as the the type of its parameters?
Yes, because you did so in a function definition.