using extern template (C++11) to avoid instantiation

You should only use extern template to force the compiler to not instantiate a template when you know that it will be instantiated somewhere else. It is used to reduce compile time and object file size.

For example:

// header.h

template<typename T>
void ReallyBigFunction()
{
    // Body
}
// source1.cpp

#include "header.h"
void something1()
{
    ReallyBigFunction<int>();
}
// source2.cpp

#include "header.h"
void something2()
{
    ReallyBigFunction<int>();
}

This will result in the following object files:

source1.o
    void something1()
    void ReallyBigFunction<int>()    // Compiled first time

source2.o
    void something2()
    void ReallyBigFunction<int>()    // Compiled second time

If both files are linked together, one void ReallyBigFunction<int>() will be discarded, resulting in wasted compile time and object file size.

To not waste compile time and object file size, there is an extern keyword which makes the compiler not compile a template function. You should use this if and only if you know it is used in the same binary somewhere else.

Changing source2.cpp to:

// source2.cpp

#include "header.h"
extern template void ReallyBigFunction<int>();
void something2()
{
    ReallyBigFunction<int>();
}

Will result in the following object files:

source1.o
    void something1()
    void ReallyBigFunction<int>() // compiled just one time

source2.o
    void something2()
    // No ReallyBigFunction<int> here because of the extern

When both of these will be linked together, the second object file will just use the symbol from the first object file. No need for discard and no wasted compile time and object file size.

This should only be used within a project, like in times when you use a template like vector<int> multiple times, you should use extern in all but one source file.

This also applies to classes and function as one, and even template member functions.

Leave a Comment