Explicit instantiation

The syntax for explicit instantiation is as follows:

template class template_name < argument_list >;
extern template class template_name < argument_list >;//(since C++11)

An explicit instantiation definition forces instantiation of the class, struct, or union they refer to. In the C++0x standard, the implicit instantiation of a template specialization or its members is suppressed. Similar to the explicit instantiation of function templates, the location of this explicit instantiation can be anywhere after its template definition, and it is only permitted to be defined once in the entire program in one file.

Moreover, since C++11, an implicit instantiation step will be bypassed by an explicit instantiation declaration (extern template). This can be used to reduce compilation times.

Going back to the template class, V, we can explicitly instantiate it as follows:

template class V<int>;
template class V<double>;

Alternatively, we can do the following (since C++11):

extern template class V<int>;
extern template class V<double>;

The compiler will present us with an error message if we explicitly instantiate a function or class template but there is no corresponding definition in the program, as shown here:

//ch4_4_class_template_explicit.cpp
#include <iostream>
using namespace std;
template <typename T> //line A
struct A {
A(T init) : val(init) {}
virtual T foo();
T val;
}; //line B
//line C
template <class T> //T in this line is template parameter
T A<T>::foo() { //the 1st T refers to function return type,
//the T in <> specifies that this function's template
//parameter is also the class template parameter
return val;
} //line D

extern template struct A<int>; //line E
#if 0 //line F
int A<int>::foo() {
return val+1;
}
#endif //line G

int main(void) {
A<double> x(5);
A<int> y(5);
cout<<"fD="<<x.foo()<<",fI="<<y.foo()<< endl;
return 0; //output: fD=5,fI=6
}

In the preceding code block, we defined a class template between lines A and B, and then we implemented its member function, foo(), from lines C to line D. Next, we explicitly instantiated it for the int type at line E. Since the code block between lines F and line G is commented out (which means that there is no corresponding definition of foo() for this explicit int type instantiation), we have a linkage error. To fix this, we need to replace #if 0 with #if 1 at line F.

Finally, there are some additional restrictions for explicit instantiation declarations, as follows:

  • Static: A static class member can be named, but a static function cannot be allowed in an explicit instantiation declaration.
  • Inline: There is no effect for inline functions in explicit instantiation declarations, and inline functions are implicitly instantiated.
  • Class and its members: It is no equivalent for explicitly instantiating a class and all its members.