C++11: extern template Explained With Simple Example

In C++11 (Introduction to C++11), extern template is added to optimize the compile time and object size. Earlier C++ compiler (C++ 03) instantiate a template function or class whenever it encounters a fully defined template function or class. If the template is used in multiple files, then compiler must create multiple instances of template function or class only to later discard all the instance but one. This would result in extra compile time and increased object file size. In C++ 03 there was no way to avoid this.

In C++11, extern template feature is introduced to avoid this situation.
Format of extern template is as follows

extern template void DemoTemplateFunction <int> ();
extern template class NUM <type>;

Above will tell the compiler to not instantiate template function or class as it is being instantiated somewhere else. Programmer should use this if and only if above template function or class is instantiated somewhere else.

Let’s have a look at the sample code to illustrate this.

// header.h

template <typename T>
void DemoTemplateFunction ()
{
    // Body
}

template <class T>
class NUM
{
    // Body
}

// source1.cpp

#include "header.h"
void demo1 ()
{
    DemoTemplateFunction <int> ();
    class NUM <int>;
}

// source2.cpp

#include "header.h"
void demo2 ()
{
    DemoTemplateFunction <int> ();
    class NUM <int>;
}

This will result in following object file.

source1.o
    void demo1 ()
    void DemoTemplateFunction <int>()    // Compiled first time
    template class NUM <int>             // Compiled first time

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

If both source file are linked, then one of the above instances will be discarded resulting wasted compile time and object size. Extern template can be used here to ensure compiler creates only one instance of template function and class.

// source2.cpp

#include "header.h"
extern template void DemoTemplateFunction <int> ();
extern template class NUM <int>;

void demo2 ()
{
    DemoTemplateFunction <int> ();
    class NUM <int>;
}

This will result in following object file.

source1.o
    void demo1 ()
    void DemoTemplateFunction <int>()    // Compiled first time
    template class NUM <int>             // Compiled first time

source2.o
    void something2()
    /* No instantiation here */

Leave a Reply

Your email address will not be published. Required fields are marked *