实例代码:
//
#include <iostream>
#include <vector>
using namespace std;
class A{ //普通类
public:
template <typename T>
void myft(T tmpt){ //成员函数模板
cout << tmpt << endl;
}
};
template<typename C> //类的模板参数
class B
{
public:
template <typename T2>
B(T2 v1, T2 v2); //构造函数我们也引入自己的模板,和整个类的模板C没有关系
template <typename T>
void myft(T tmpt){ //成员函数模板
cout << tmpt << endl;
}
void myftpt(){}
C m_ic;
};
template <typename C> //先跟类的模板参数列表
template <typename T2> //再跟构造函数自己的模板参数列表
B<C>::B(T2 v1, T2 v2){
cout << v1 << v2 << endl;
}
template <typename T>
void myfunc123(T v1, T v2){
cout << v1 + v2 << endl;
}
//“显式实例化” 手段中的“实例化定义”,这种实例化定义只需要在一个.cpp文件写就可以。
template B<float>; //编译器遇到这段代码就直接实例化出来一个 B<float>
template void myfunc123(int v1, int v2); //编译器会为其生成代码
//"显式实例化" 手段中的 “实例化声明”
//extern template B<float>; //其他所有.cpp 文件都这么写;
//extern 作用: 不会在本文件中生成一个extern后边所表示的模板的实例化版本代码。
//extern 目的: 告诉编译器,在其他的源文件(.cpp文件)中已经有了一个该模板的实例化版本了。
//extern template void myfunc123(int v1, int v2);
void mfunc(){
B<float> b(1, 2);
}
int main()
{
//一:普通类的成员函数模板
//不管是普通类,还是类模板,它的成员函数可以是一个函数模板,称为 “成员函数模板”,不可以是虚函数,否则编译器会报错。
A a;
a.myft(3); //编译器在遇到这条语句时,编译器就和ui实例化这个函数模板
//二:类模板的成员函数模板
B<float> b(1, 2);
B<float> b2(1.1, 2.2);
//类模板的成员函数 (包括普通成员函数/成员函数模板)只有为程序所用(代码中出现了对该函数模板的调用时)才进行实例化
//如果某含从未使用,则不会实例化该成员函数。
b.myftpt();
b.myft(12);
//三:模板显式实例化,模板声明
//为了防止在过个.cpp文件中都实例化相同的类模板,所以C++提出了一个解决方法,我们称为“显式实例化”;
//通过 “显式实例化”来比那种生成多个相同类模板实例的开销。
B<int> tmpobj(6, 7);
//模板的实例化定义只有1个,实例化声明可以有多个。
//总结:
//(1) vs2017不太推荐这个特色
//(2)
// template B<float>
// extern template B<float>;
system("pause");
}