普通类的成员函数模板
不管是普通类还是类模板,它的成员函数可以是一个函数模板(成为成员函数模板)。不可以是虚函数,否则编译器会报错。
//普通类的成员函数模板
class A
{
public:
template<typename T>
void my_ft(T tmp) //成员函数模板
{
cout << tmp << endl;
}
};
int main()
{
//普通类的成员函数模板
A a;
a.my_ft(3);
//类模板的成员函数模板
B<float> b(1, 2);
return 0;
}
类模板的成员函数模板
//类模板的成员函数模板
//类模板的模板参数必须用<>指定, 成员函数模板(函数模板)的参数都可以推断
template<typename C>
class B
{
public:
template <typename T2>
B(T2 v1, T2 v2);//构造函数也引入自己的模板,和整个类的模板C无关
template<typename T>
void my_ft(T tmp)
{
cout << tmp << endl;
}
void my_ft_nomal()
{
}
public:
C m_ic;
};
template <typename C> //类的模板参数列表
template <typename T2>
B<C>::B(T2 v1, T2 v2) //构造函数也引入自己的模板,和整个类的模板C无关
{
cout << v1 << " " << v2 << endl;
}
int main()
{
//类模板的成员函数模板
B<float> b(1, 2);
//类模板的成员函数(包括普通成员函数/成员函数模板) 只有为程序所用(代码中出现了 对该函数或者该函数模板的调用时)才进行实例化该成员函数
//如果某函数从未使用,则不会实例化该成员函数
return 0;
}
模板显式实例化/模板声明
为了防止在多个.cpp文件中都实例化相同的类模板,C++11提出了一种解决方法,成为显式实例化;
通过该方法来避免这种生成多个相同类模板实力的开销。
函数模板与类模板类似
//显式实例化 实例化定义 只需要在一个.cpp文件中写就行
template B<float>; //编译器遇到这段代码就直接实例化出来一个A<float>
//显式实例化 实例化声明 其它所有.cpp文件中多用
extern template B<float>
//extern作用:不会再本文件中生成一个extern后边所表示的模板的实例化版本代码
//目的:告诉编译器,已经有一个该模板的实例化版本了。需要再实例化了
template void myfunc(int x, int y);//实例化定义
extern template void myfunc(int x, int y);//实例化声明
模板的实例化定义只有一个,实例化声明可以有多个;