前言
在上一次的STL学习中,明白了关于C++标准库中的的第一个内部使用对象I/O对象的使用,包括基本的输入输出,与文件内容的输入输出,顺便学习了系统操作参数int argc 与char* argv[],与对STL更为方便的函数表达式——lambda表达式:
[capture list] (params list) mutable exception-> return type { function body }
今天我们就要开始第二部学习,学习STL中的序列容器库。
本来是打算这么做的,但是之后尝试学习阅读一些函数非常吃力,因为有些内容应该在之后才会学的在我的那个学习路径中提前用了,这样不仅会导致学习十分吃力,并且基础十分不牢。所以。。不如回到最初的起点,重头开始。
时间回溯中。。
欢迎回到最初的起点!
函数模板
函数模板的作用
看一段代码:
//函数:交换两个int数
void Myswap(int& a, int& b){
int temp = a;
a = b;
b = temp;
}
//函数:交换两个double数
void Myswap(double& a, double& b){
double temp = a;
a = b;
b = temp;
}
两个函数只有参数不一样,业务逻辑都是一样的,如果为了变量类型不同要写如此多的函数的话,不仅占空间,增加可执行文件的大小。而且重复劳动,容易出错,增加维护成本。所以使用模板技术。
模板技术的好处是可以使得类型参数化,即编写代码可以忽略类型,用一个标志/符号代替所有类型。
为了让编译器区分是普通函数还是模板函数,这样书写:
template<class T> //也可以用template<typename T>,并且class后面可以接不知一个参数可以是<class T1, class T2>
//告诉编译器,下面写模板函数,不要随便报错
void MySwap(T& a,T& b){
double temp = a;
a = b;
b = temp;
}
//注意:template只对它后面第一个函数生效
//并且class后面可以接不知一个参数可以是<class T1, class T2>
使用的方法:
void test01() {
int a = 10;
int b = 20;
//1.自动类型推导
cout << "a:" << a << "b:" << b;
MySwap(a,b);
cout << "a:" << a << "b:" << b;
double da = 1.1;
double db = 1.2;
cout << "a:" << a << "b:" << b;
MySwap(a,b);
cout << "a:" << a << "b:" << b;
//函数调用时如果你不给它指定调用的参数类型,编译器会根据传的值会自动推导来用推导出来的结果替换T
//2.显式的指定类型
MySwap<int>(a,b);
其中有一点:函数模板不允许自动类型转化,普通函数允许自动类型转化
举个栗子:
template<class T>
int Myadd(T a,T b){
return a+b;
}
//函数模板必须严格的类型类型匹配
int MyAdd(int a, char c){
return a+c;
}
//普通函数可以进行自动类型转换
void test02(){
int a = 10;
int b = 20;
char c1 = 'a';
MyAdd(a, c); //调用普通函数
MyAdd(a, b); //调用函数模板
MyAdd(c, b); //我们发现调用是普通函数
}
函数模板和普通函数的调用规则:
1.函数模板可以像普通函数一样被重载:
template<class T>
void Print(T a){
}
void Print(T a,T b){
}
2.编译器优先考虑普通函数
函数在调用的时候,编译器会先调用普通函数,普通函数不满足的时候再考虑用模板函数匹配
模板函数实现原理
做手链模子 - 生产具体的手链 - 再戴手上
同理:由函数模板,生成模板函数,再被使用。
MySwap(float, float) //会生成一个float类型的模板函数
MySwap(int, int) //会生成一个int类型的模板函数
编译器并不把函数模板处理成能处理任何类型的函数
函数模板通过具体类型产生不同的函数
编译器会对函数模板进行两次编译,在声明的地方对模板代码本身进行编译,在调用的地方对参数替换后的代码再进行第二次编译。
结尾
STL开始从头开始,其实也就之前没开始多久。不过还好提前意识到了前一种学习路径其实涉及大量提前内容,对于我来说势必会造成许多的困扰。不如从头用一种更为基础的方式去深入,想必在基础巩固的同时,道路也会轻松不少。