Understanding Template Instantiation
Gain a deep understanding of template instantiation in this lesson.
We'll cover the following...
As mentioned before, templates are only blueprints from which the compiler creates actual code when it encounters their use. The act of creating a definition for a function, a class, or a variable from the template declaration is called template instantiation. This can be either explicit, when we tell the compiler when it should generate a definition, or implicit, when the compiler generates a new definition as needed. We’ll look at these two forms in detail in this lesson.
Implicit instantiation
Implicit instantiation occurs when the compiler generates definitions based on the use of templates and when no explicit instantiation is present. Implicitly instantiated templates are defined in the same namespace as the template. However, the way compilers create definitions from templates may differ. This is something we will see in the following example. Let’s consider this code:
template<typename T>struct foo{void f() {}};int main() {foo<int> x;}
Here, we have a class template called foo
with a member function f
. In main
, we define a variable of the type foo<int>
but do not use any of its members. Because it encounters this use of foo
, the compiler implicitly defines a specialization of foo
for the int
type. If we use C++ Insights, which runs in Clang, we’ll see the following code:
template<>struct foo<int>{inline void f();};
Because the function f
is not invoked in our code, it’s only declared but not defined. Should we add a call f
in main
, the specialization would change as follows:
template<>struct foo<int>{inline void f() {}};
However, if we add one more function, g
, with the following implementation that contains an error, we’ll get different behaviors with different compilers:
template<typename T>struct foo{void f() {}void g() {int a = "42";}};int main() {foo<int> x;x.f();}
The body of g
contains an error (we could also use a static_assert(false)
statement as an alternative). This code compiles without any problem with VC++ but fails with Clang and GCC. This is because VC++ ignores the parts of the template that are not used, provided that the code is syntactically correct, but the others perform semantic validation before proceeding with template instantiation.
For function templates, implicit instantiation occurs when the user code refers to a function in a context that requires its definition to exist. For class templates, implicit instantiation occurs when the user code refers to a template in a context when a complete type is required or when the completeness of the type affects the code. The typical example of such a context is when an object of such a ...