1.普通类的成员函数模板
不管是普通类还是模板类,成员函数都可以是函数模板,称为“成员函数模板”,但不可以是虚函数,否则编译器报错。
2.类模板的模板参数必须用<>指定,成员函数模板(函数模板)的模板参数可以自动推导。
3.类模板的成员函数(普通成员函数/函数模板)只有为程序所用时(代码对函数或函数模板进行调用时)才实例化。 如果某函数从未使用,则不会实例化该函数。
//普通类
class A{
public:
template<class T> //成员函数模板
void myfunc(T tempVal)
cout << tempval <<endl;
}
A a;
a.myfunc(3);//模板函数自动类型推断
//编译器遇到这条语句,将函数模板实例化。模板,不使用,不实例化。
//类模板的成员函数模板
template<class C>
class A{
public:
template<class T2>
A(T2 v1, T2 v2){
//构造函数模板
}
template<class T> //成员函数模板
void myfunc(T tempVal)
cout << tempval <<endl;
void myfpt(){
//普通成员函数
}
C m_ic;
}
A<float> a(1,2); //类模板的模板参数必须指定,函数模板自动推导。
A<float> a(1.1, 2.2);
a.myfpt(); //调用时,才实例化该函数
成员函数外部实现
template<class C> //先跟类模板的模板函数列表
template<class T2> //构造函数自己的模板函数列表
A<C>::A(T2 v1, T2 v2){
cout << v1 << v2 << endl; //构造函数模板
}
4.为例防止在多个源文件中实例化相同的类模板,C++11提出了“显示实例化”
5.模板的实例化定义只有一个,实例化声明可以有多个。
类模板的显示实例化
显示实例化,在一个.cpp文件中“实例化定义”即可,其他.cpp文件中进行“实例化声明”
如在XXX1.cpp中
template A<float> ; //编译器碰到这段代码,直接实例化一个A<float>类
void myfunc(){
A<float> a(1,2);
}
在XXX2.cpp中的最前面
extern template A<float> ; //实例化声明,其他所有.cpp都这么写
//extern作用:不会在本文件中生成 一个extern后面所表示的模板的实例化代码
函数模板的显示实例化
在.h 定义一函数模板
template<class T>
void funtest(T v1, T v2){
cout << v1 + v2 << endl;
}
如在XXX1.cpp中
template void funtest(int v1, int v2); //编译器会为其生成代码
如在XXX2.cpp中
extern void funtest(int v1, int v2) ;