Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 283
Itachi Uchiwa Avatar asked Oct 20 '21 20:10

Itachi Uchiwa


1 Answers

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.

like image 121
StoryTeller - Unslander Monica Avatar answered Nov 15 '22 09:11

StoryTeller - Unslander Monica