模板显式实例化(extern template)可以用来确保模板只被编译器实例化一次,有两个好处:

  1. 这样使用模板生成的编译单元不会重复实例化,会加快编译速度,并减小编译单元的尺寸
  2. 如果模板类中包含静态成员对象,当这种模板类被多个动态库(如dll,so)使用,这样生成的动态库会分别包含一份静态成员数据,容易导致程序异常。(在libstdc++中导出std::string就用了这种机制)

例子

// MyClass.h

#ifndef _MYCLSSS_H_
#define _MYCLSSS_H_

template<typename T>
class MyClass
{
public:
    void set(T t) { m_val = t; }
    T get() { return m_val; }
    
private:
    T m_val;
};

// extern template声明:防止编译器实例化
extern template class MyClass<int>;

#endif
// MyClass.cpp
#include "MyClass.h"

// 显式实例化一次,与此相对的是隐式实例化:MyClass<int> myClass;
template class MyClass<int>;
// main.cpp
#include "MyClass.h"

int main(int argc, const char * argv[]) {    
    MyClass<int> cls;
    cls.set(5);
    
    return 0;
}

参考