Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ template "deferred instantiation"

Tags:

c++

templates

What is meant with "deferred instantiation" in C++ templates?

like image 391
Tony The Lion Avatar asked Sep 08 '10 09:09

Tony The Lion


2 Answers

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
like image 103
sharptooth Avatar answered Sep 30 '22 02:09

sharptooth


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.

like image 40
Johannes Schaub - litb Avatar answered Sep 30 '22 01:09

Johannes Schaub - litb