模板显式实例化
为了防止多个.cpp文件中都实例化相同的类模版,C++ 11中提出了一个解决方法,我们称之为“模版显式实例化”,通过模版显式实例化来避免这种生成多个相同类模版实例的开销。
模板实例化的使用方法是在一个.cpp文件中进行模板实例化定义,其余需要使用该类型的.cpp文件中进行模板实例化声明就可以了。具体看如下案例:
cpp
/* class a的头文件 ca.h */
#ifndef __CA_H__
#define __CA_H__
#include <iostream>
template <typename T>
class A{
public:
A(){}
A(T value1, T value2);
};
template <typename T>
A<T>::A(T value1, T value2){
std::cout << value1 + value2 << std::endl;
}
#endif //__CA_H__
假如现在有两个.cpp文件,都想实例化一个double类型的对象,那么程序在编译的时间就会为每个.cpp文件实例化出来一份double类型的class A的代码。模板显式实例化就是只在一个.cpp文件中实例化一份double类型的class A的代码,其他.cpp文件中如果也想使用double类型的class A实例化对象只需要引用这份代码就可以了,你不用自己生成,用我已经生成好的代码就可以了。
理解了这个逻辑,我们让test01.cpp来实例化代码,test02.cpp进行引用。那么test01.cpp中就要在文件的最上面进行模板实例化定义,test02.cpp的最上面进行引用。
cpp
#include "ca.h"
//模板显式实例化定义
template A<double>;
int main(){
//实例化一个double类型的对象a1
A<double> a1(3.2, 2.2);
return 0;
}
cpp
#include "ca.h"
//模板显式实例化声明
template A<double>;
int main(){
//实例化一个double类型的对象a1
A<double> a1(3.2, 2.2);
return 0;
}
这样就只产生了一份double类型的class A的实例化代码,却同时在另个.cpp文件中进行使用了。上面只是针对于类模板的使用,如果是函数模板可以进行下面形式的定义和引用。
cpp
template void sum(double value1, double value2);
extern template void sum(double value1, double value2);
- 实例化定义只有一个;
- 实例化声明可以有许多个。
如果你自己不明确编译器对该特性的支持,不是很建议使用这个特性。