函数模板:实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就是函数模板。
C++提供两种模板机制:函数模板,类模板。
函数模板定义形式: template <类型形式参数表>
类型形式参数形式如:typename T1,typename T2,…
函数模板的概念:
部分代码:
#include
using namespace std;
template //声明T是虚拟类型
T add(T x, T y)
{
return x + y;
}
template <typename T1, typename T2, typename T3>
T1 print(T2 x, T2 y, T3 z)
{
cout << x << " " << y << " " << z << endl;
}
int main()
{
int a = 1, b = 2;
float c = 1.11, d = 2.22;
cout << add(a, b) << endl; //隐式调用
cout << add<int>(a, b) << endl; //显式调用
cout << add(c, d) << endl;
print<char, int, float>(a, b, c); //必须显式调用
char ch = 'a';
add<char>(a, ch); //函数模板和普通函数的区别:普通函数能够自动进行类型转换,模板函数不能进行类型转换
return 0;
}
函数模板声明:
1.函数模板定义由模板说明和函数定义组成
2.模板说明的类属参数必须在函数定义中出现一次
3.函数参数表中可以使用类属类型参数。也可以使用一般类型参数。
函数模板和普通参数区别:
函数模板不允许自动模板转换。
普通函数能够进行自动模板转换。
模板函数和普通函数:
部分代码:
#include
using namespace std;
void print(int a, int b)
{
cout << “void print(int a, int b)” << endl;
cout << a << " " << b << endl;
}
template
void print(T a, T b)
{
cout << “void print(T a, T b)” << endl;
cout << a << " " << b << endl;
}
int main()
{
print(1, 2); //优先调用普通函数
print(1.11, 2.22);
print(‘a’, ‘b’);
return 0;
}
函数模板机制:
编译器并不是把函数模板处理成能够处理任意类的函数。
编译器从函数模板中通过具体类型产生不同的函数。
编译器对函数模板进行两次编译。
在声明的地方对模板代码本身进行编译;在调用的地方对参数替换后的代码进行编译。
单个类模板语法:
template <类型形式参数表>
例如:template
类模板概念:
#include
using namespace std;
template<typename T1, typename T2, typename T3>
class Test //模板类
{
private:
T1 m_a;
T2 m_b;
public:
Test(T1 a, T2 b)
{
m_a = a;
m_b = b;
}
T3 print()
{
cout << m_a << " " << m_b << endl;
}
};
int main()
{
Test<int, int, char> t(1, 2); //必须显示调用
return 0;
}
类模板派生:
#include
using namespace std;
template
class TestA
{
public:
T m_a;
public:
TestA(T a)
{
m_a = a;
}
};
class TestB : public TestA //模板类派生普通类
{
private:
int m_b;
public:
TestB(int a, int b) : TestA(a)
{
m_b = b;
}
void show()
{
cout << m_a << " " << m_b << endl;
}
};
template
class TestC : public TestA //模板类派生出模板类
{
private:
T m_c;
public:
TestC(T a, T c) : TestA(a)
{
m_c = c;
}
void show()
{
cout << TestA<T>::m_a << " " << m_c << endl;
}
};
int main()
{
TestB tb(1, 2);
tb.show();
TestC<int> tc(1, 2);
tc.show();
return 0;
}
类模板的相关说明:
1.先写出一个实际的类。由于其语意明确,含义清楚,一般不会出错。
2.将此类中的准备改变的类型名改用一个自己制定的虚拟类型名。
3.在类声明前面加入一行,格式为:
template <typename 虚拟类型参数>
4.用类模板定义对象时用以下形式:
类模板名 <实际类型名> 对象名。
类模板名 <实际类型名> 对象名(实参表列)。
5。如果在类模板外定义成员函数,应写成模板形式;
关于类模板的几点说明
1.类模板的类型可以有一个或多个,每个类型前面都必须加 typename
2使用模板时要注意其作用域
3.模板可以有层次,一个类模板可以作为一个基类,派生出派生模板类。
类模板中的static关键字:
1.模板类的所有成员共享一个static数据成员。
2.与非模版的static数据成员一样,模板类的static数据成员也应该在文件范围内定义和初始化。
3.每个模板都有自己的类模板static数据成员副本。
部分代码:
#include
using namespace std;
template
class Test
{
public:
static T m_a;
public:
Test()
{
m_a++;
}
};
template
T Test::m_a = 0;
int main()
{
Test t1;
Test t2;
Test t3;
Test<float> t4;
Test<float> t5;
cout << Test<int>::m_a << endl;
cout << t1.m_a << endl;
cout << Test<float>::m_a << endl;
cout << t4.m_a << endl;
return 0;
}