模板显式实例化(extern template)可以用来确保模板只被编译器实例化一次,有两个好处:
- 这样使用模板生成的编译单元不会重复实例化,会加快编译速度,并减小编译单元的尺寸
- 如果模板类中包含静态成员对象,当这种模板类被多个动态库(如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;
}
参考
- http://www.stroustrup.com/C++11FAQ.html#extern-templates
- https://msdn.microsoft.com/en-us/library/by56e477.aspx
- http://stackoverflow.com/questions/8130602/using-extern-template-c0x
- http://en.cppreference.com/w/cpp/language/class_template
- extern Templates (C++0x)
- https://support.microsoft.com/en-us/kb/168958