网站建设推广页,旅游网站建设备案,市场调研的四个步骤,wordpress 树莓派前言
模板作为 C 的一大特色#xff0c;对于泛型编程有着重要的作用。同时#xff0c;对于大规模类似的函数或是类型不确定的类#xff0c;模板都起了至关重要的作用。
一、模板
在开始学习模板之前#xff0c;我们首先需要了解模板。先看下面一个例子#xff1a;
#in…前言
模板作为 C 的一大特色对于泛型编程有着重要的作用。同时对于大规模类似的函数或是类型不确定的类模板都起了至关重要的作用。
一、模板
在开始学习模板之前我们首先需要了解模板。先看下面一个例子
#include iostream
using namespace std;int func_one(int num){return 2 * num;
}double func_two(double num){return 2 * num;
}int main(){int num_int 2;double num_double 2;func_one(num_int);func_two(num_doule);return 0;
}我们可以轻易发现对于函数 func_one、func_two两者实现的功能基本相同只是所接受的参数和返回值发生了对应的变化。因此有没有一种办法可以简化这两个函数将其合并为一个呢答案就是使用模板。
下面的例子是对上面的两个函数使用模板的结果
#include iostream
using namespace std;template class T
T func(T num){return 2 * num;
}int main(){int num_int 2;double num_double 2;func(num_int);func(num_doule);return 0;
}在上面的案例中我们见到了新的关键字 template。它表示此处运用模板后面 中则表示有一个模板类型 TT 在此会根据我们函数的传参自动生成对应的类型。例如 num_int 传入后 T 则代表 int num_double 传入后 T 则代表 double。 模板就像一个空的模具大体上不会改变但是你提供什么参数都可以按照模具的形状进行操作。 二、函数模板
在上面介绍时我们使用的模板就是函数模板除此之外还有类模板但是我们先从函数模板开始讲起。
2.1 模板的格式
**函数模板代表了一个函数家族该函数模板与类型无关在使用时被参数化根据实参类型产生函数的特定类型版本。**函数模板的诞生是为了简化重复的函数哪怕利用重载也需要对一个函数进行多次重载但是模板函数只需一个模板即可适应各个种类。 函数模板的格式如下 template class T1, typename T2, class T3, … , typename TN 返回值类型 函数名(参数列表){ 函数主体; } 声明一个模板类型的时候可以使用 “class” 或 “typename”两者无差别。但是需要注意的地方在于一个模板类型只能代表一种类型。例如在上面的函数中T1 实例化为 int 类型后就不能再代表 char 等类型具体如下
#include iostream
using namespace std;template class T1
double func_one(T1 num_1, T1 num_2){return num_1 num_2;
}template class T1, class T2
double func_two(T1 num_1, T2 num_2){return num_1 num_2;
}int main(){int num_int 2;double num_double 2;func_one(num_int, num_double);func_two(num_doule, num_double);return 0;
}在这个例子中主函数中调用 func_one 是失败的T1 在接收 num_1 时已经实例化为 int, 但是 num_2 为 double 类型因此发生了错误。为接收不同类型的两个参数我们可以考虑使用 func_two。
2.2 模板的匹配优先度
先看下面的案例猜测系统会调用哪个函数。
#include iostream
using namespace std;int func(int num_1, int num_2){return num_1 num_2;
}template class T1
int func(T1 num_1, T1 num_2){return num_1 num_2;
}int main(){int num_1 1;int num_2 2;func(num_1, num_2);funcint(num_1, num_2);return 0;
}经过调试我们可以得知
第一次调用 func 函数调用的是第一个非模板的 func 函数这是由于在可以找到匹配的函数时优先不调用模板函数避免重复生成一个一样的函数
第二次调用 func 函数调用的模板生成函数这是由于 func(), 表示我们手动要求生成一个 func 模板函数用 int 实例化之后的函数此时会优先采用手动要求的模板函数。
2.3 模板的声明
比起其他的函数模板函数要求必须声明和定义在一起不可声明与定义分离。此过程涉及到编译链接的过程不在此展开。
三、类模板
在了解了函数模板之后类模板也非常好理解例如我们之后会学到的 vector 容器就是一个模板类
#include iostream
using namespace std;template class T
class vector{
private:T* ptr;
public:vector(T num){// ......}
}在这个类中构造一个类时需要传入一个类型作为参数然后 ptr 的类型就确定了之后的函数就可以据此继续完成。之后将以 vector 为例讲述一个模板类的实现。
四、总结
模板的优点显而易见一方面节省了资源便于代码的迭代更新另一方面增加了代码的灵活性。那是不是我们要多多使用模板呢答案是否定的。
首先模板相比于普通的函数需要的编译时间更长且出现错误信息时不易定位错误位置。所以具体使用重载还是模板要根据实际情况来合理进行判断选取。