What is meant with "deferred instantiation" in C++ templates?
Deferred instantiation is when the template is not instantiated until the corresponding entity is used for the first time. For example, you have a templated function:
template<int Size>
void YourFunction()
{
//does something
}
parameter Size
can have any possible value that int
can have. Do you automatically have the templated function instantiated for all possible values of Size
? No, the template is only instantiated for the values that are actually used as the parameter when the function call first appears in the code:
YourFunction<100>(); //instantiated for 100
I have only heard people use the term "deferred instantiation" to refer to the situation where a class member definition is instantiated only if it is used
template<typename T>
struct A {
void f() {
T a; // invalid if T is void
}
};
A<void> a; // valid!
In this case, A<void>
is implicitly instantiated because the compiler needs to know its size (formally, the class type needs to be complete, so an instantiation is triggered). But the instantiation of its member definitions are deferred until they are actually used. This does not only apply to member functions, but also to static data members and nested classes
struct Print {
Print() { std::cout << "hello!"; }
};
template<typename T>
struct A {
static Print print;
};
template<typename T>
Print A<T>::print;
Now even if you implicitly instantiate A<T>
the message won't be printed until you explicitly refer to A<T>::print
and use it. Explicit instantiation won't defer instantiation of member definitions - so the following will always print the message
template struct A<void>;
There is a trick to trigger instantiation of member definitions for implicit instantiations though: Refer to them in declaration parts of a class' member, like in the following changed class template
template<typename T, T&> struct useit { };
template<typename T>
struct A {
static Print print;
typedef useit<Print, print> useit_type;
};
Now if A<T>
is implicitly instantiated the message is printed, because the typedef declaration refers to it.