explicit template instantiation

From Cppwiki

Jump to: navigation, search

Typically, a function is instantiated (turned into machine-executable code) when it is defined. This allows you to define a function in one .cpp file, then declare it (usually in a header file) and call it from other .cpp files:

/* main.cpp */
 
#include "square.h"
#include <iostream>
 
int main() {
   std::cout << square(5) << '\n';
   std::cout << square(1.9) << '\n';
}
 
/* square.h */
 
int    square(int x);
double square(double x);
 
/* square.cpp */
 
int    square(int    x) { return x * x; }
double square(double x) { return x * x; }

In general, this cannot be done with function templates. Simply changing square to a template will elicit undefined reference linker errors, even though the template is defined in a .cpp file:

/* square.h */
 
template <typename T>
T square(T x);
 
/* square.cpp */
 
template <typename T>
T square(T x) {
  return x * x;
}

That's because function templates are instantiated when they are called, not when they are defined. In order to do this, the definition of the template must be available when it is called. In other words, template definitions almost always need to appear in header files, not .cpp files:

/* square.h */
 
template <typename T>
T square(T x) {
  return x * x;
}
 
/* there is no square.cpp */

As an exception to this rule, if you know the parameters for which your template will be instantiated, you can use explicit template instantiation to instantiate your template using those parameters:

/* square.h */
 
template <typename T>
T square(T x);
 
/* square.cpp */
 
template <typename T>
T square(T x) {
  return x * x;
}
 
// EXPLICIT TEMPLATE INSTANTIATION
template int    square(int x);
template double square(double x);

Here, we manually tell the compiler to do for our template int square(int x) what it did automatically for the non-template int square(int x) — namely, to instantiate it in square.cpp.

Personal tools