这一章主要讲模板函数和泛型的定义,主要用法和作用,简单写了一下和普通函数的异同。
本文主要为学习心得笔记,如有纰漏,欢迎指正
当你写了一个交换函数,交换传入参数的值,例如:
void mySwap(int &a, int &b)
{
int temp = a;
a = b;
b = temp;
}
你会发现两个问题:
//声明创建模板
//函数返回值 函数名(参数列表) { 函数主体 }
template<typename T>
void func()
{ // 代码块}
//或:
template<class T>
void func()
{ // 代码块}
//第一种方式:
函数名(参数列表);
//第二种方式:
函数名<指定数据类型>(参数列表);
template<typename T>
void mySwap(T &a, T &b)
{
T temp = a;
a = b;
b = temp;
}
void test1()
{
long a = 10;
long b = 20;
//两种方式使用函数模板
//第一种方式:
mySwap(a, b);
//第二种方式:
//mySwap(a, b);
cout << "a = " << a << endl
<< "b = " << b << endl;
}
注意:
template<typename T>
void print()
{
cout << "打印函数" << endl;
}
void test2()
{
print<int>(); //如果模板函数无法判断泛型类型,则必须写上类型
}
template<typename T>
void myPrint(T a, T b) //不要传引用
{
cout << a << endl;
cout << b << endl;
}
void test1()
{
int a = 10;
char b = 'a';
// 这样写是错误的,编译器无法确定转化的数据类型
//mySwap(a, b);
// 这种写法可以使两个变量发生隐式类型转换
myPrint<int>(a, b);
}
注:
void myPrint(int a, int b)
{
cout << "普通函数" << endl;
}
template<typename T>
void myPrint(T a, T b)
{
cout << "模板函数" << endl;
}
template<typename T>
void myPrint(T a, T b, T c)
{
cout << "重载模板函数" << endl;
}
void test3()
{
int a = 1;
int b = 1;
// 优先调用普通函数
myPrint(a, b); // => 普通函数
//强制调用模板函数,写不写数据类型都可以
myPrint<int>(a, b); // => 模板函数
myPrint<>(a, b); // => 模板函数
//重载
myPrint(a, b, 10); // => 重载模板函数
//发生更好的匹配时,优先调用不需要类型转化的
myPrint('a', 'b'); // => 模板函数
}
注:
例:当你想实现两个数值的交换,但是传进来一个数组(各种不符合这个函数功能的数据);
这个时候用原有的方式无法对这种情况做处理,很容易出问题。
class Person
{
public:
string name;
int age;
Person(string name, int age)
{
this->name = name;
this->age = age;
}
};
//模板函数
template<typename T>
bool myCmp(T& a, T& b)
{
return a == b;
}
//Person版本具体化实现
template<>
bool myCmp(Person& a, Person& b)
{
return (a.name == b.name && a.age == b.age);
}
void test4()
{
Person p1("gzy", 10);
Person p2(p1);
Person p3(p1);
p3.name = "张利伟";
cout << (myCmp(p1, p2) ? "相等" : "不相等") << endl; // => 相等
cout << (myCmp(p1, p3) ? "相等" : "不相等") << endl; // => 不相等
}
函数模板的学习一个目的是学习模板的使用编写,更大的作用是理解stl库的容器使用,为后面的学习做铺垫。