当前位置: 首页> 教育> 锐评 > 自助建站系统搭建网站_东莞seo公司_河南seo_海外免费网站推广

自助建站系统搭建网站_东莞seo公司_河南seo_海外免费网站推广

时间:2025/8/25 0:30:02来源:https://blog.csdn.net/2401_87588283/article/details/147312832 浏览次数:0次
自助建站系统搭建网站_东莞seo公司_河南seo_海外免费网站推广

目录

函数模板

函数模板概念

函数模板格式

函数模板的原理

函数模板的实例化

模板参数的匹配原则

类模板

类模板的定义格式

类模板的显式实例化 


当面对下面的代码时,大家会不会有一种无力的感觉?明明这些代码差不多,只是因为类型不同,就要多写几行代码。如果有泛型编程该有多好! 

void swap(int& left, int& right)
{int tmp = left;left = right;right = tmp;
}
void swap(double& left, double& right)
{double tmp = left;left = right;right = tmp;
}
void swap(char& left, char& right)
{char tmp = left;left = right;right = tmp;
}

虽然在这种情况下,函数重载也可以实现,但是有以下几个不好的地方:

  1. 重载的函数仅仅是类型不同,代码复用效率比较低,只有当新类型出现时,就需要用户自己增加对应的函数。
  2. 代码的可维护性比较低,一个出错所有重载均出错。

那是否能告诉编译器一个模子,让编译器根据不同的类型利用该模子生成代码呢?这就要讲到我们今天的内容了——模板。

函数模板

函数模板概念

函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化根据实参类型产生函数的特定版本。

函数模板格式

#include<iostream>
using namespace std;
template <typename t>
//typename是用来定义模板参数关键字,也可以用class(不能用struct
void swap(t& x, t& y)
{t tmp = x;x = y;y = tmp;
}
int main()
{return 0;
}

函数模板的原理

函数模板是一个蓝图,它本身并不是函数,是编译器使用方式产生了特定具体类型函数的模具。所以模板其实就是将本来该由我们做的重复的事情交给了编译器。

        编译器编译阶段,对于函数模板的使用,编译器需要根据传入的实参类型来推演生成对应类型的函数来调用 。

函数模板的实例化

用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化。

1.隐式实例化:模板参数根据实参自动推演。

#include<iostream>
using namespace std;
template<typename T>
T add(T x, T y)
{return x + y;
}
int main()
{int a1 = 10, a2 = 22;double d1 = 10.23, d2 = 45.23;//隐式实例化add(a1, a2);add(d1, d2);//在模板中,编译器一般不会进行类型转换操作,因为一旦转化出现问题,编译器就需要背黑锅//add(a1, d1);//有两种解决方法:1.用户自己来强制转化2.使用显式实例化add(a1,(int)d1);return 0;
}

2. 显式实例化:在函数名后的<>中指定模板参数的实际类型

int main()
{int a1 = 10, a2 = 22;double d1 = 10.23, d2 = 45.23;//显式实例化add<int>(a1, a2);add<double>(d1, d2);add<int>(a1, d1);return 0;
}

模板参数的匹配原则

  • 一个非模板函数和一个同名函数模板可以同时存在 ,而且该函数模板还可以被实例化为这个非模板函数(现成的非模板函数优先)。

#include<iostream>
using namespace std;
template<typename T>
T add(T x, T y)
{cout << "模板" << endl;return x + y;
}
int add(int x, int y)
{cout << "现成" << endl;return x + y;
}
int main()
{int a1 = 10, a2 = 22;double d1 = 10.23, d2 = 45.23;add(a1, a2);return 0;
}

 

  • 对于非模板函数和一个同名函数,我们都可以调用,但会调用更匹配的。
#include<iostream>
using namespace std;
template<typename T1,typename T2>
T1 add(T1 x, T2 y)
{cout << "模板" << endl;return x + y;
}
int add(int x, int y)
{cout << "现成" << endl;return x + y;
}
int main()
{int a1 = 10, a2 = 22;double d1 = 10.23, d2 = 45.23;add(a1, d2);return 0;
}

 

 可以看出编译器会优先调用更匹配的模板,即使它比较麻烦。

类模板

基本都是显式实例化,因为无法借助数来推是什么类型

类模板的定义格式

template<class T1, class T2>
class t//类模板名
{};

举例:

#include<iostream>
using namespace std;
template<class T>
class stack
{
public:stack(size_t capacity = 4){_array = new T[capacity];_capacity = capacity;_size = 0;}void Push(const T& data);
private:T* _array;size_t _capacity;size_t _size;
};
template<class T>
void stack<T>::Push(const T& data)
{_array[_size] = data;++_size;
}
int main()
{stack<int>st1;return 0;
}

类模板的显式实例化 

实例化模板需要在类模板后加<>,然后将实例化的类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类。

int main()
{stack<int>st1;return 0;
}

 

 

 

关键字:自助建站系统搭建网站_东莞seo公司_河南seo_海外免费网站推广

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: