When a template is instantiated?

The fact that a template is not instantiated until it is used so for example if I have this class template:

template <typename T>
struct Pow{
    T operator()(T const& x) const{ return x * x; }
};

void func(Pow<double>); // Pow<double> instantiated here?
void func(Pow<int>){}   // Pow<int> instantiated here?

int main(){
    Pow<int> pi; // instantiated here?
    func(pi); // Pow<int> instantiated here
}
  • So when exactly the template is instantiated?

  • So is Pow<int> instantiated when func(Pow<int>) is declared?

  • 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?

Answer

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.