C++(十五):模板

模板

C++的另一种编程思想是泛型编程,其主要利用的技术就是模板。模板树妖分为两类: 函数模板类模板

1.函数模板

所谓函数模板,就是一个返回值和形参类型不用具体指定的通用函数,是一个虚拟的类型。

其目的是提高代码的复用性,将类型参数化。

1.1 语法

template<typename T>
函数声明或者定义

其中,

  1. template——声明创建模板
  2. typename——表明其后面的符号是一种数据类型,也可以用class代替
  3. T——通用数据类型,任意规范的名称均可,一般为大写字母

1.2 范例

这里写一个简单的实例:

#include <iostream>
#include <string>

using namespace std;

template<typename T>//模板声明,表明后面紧跟着的T是一个通用数据类型,编译器不应该报错
void myswap(T &a, T &b)
{
   
	T temp = a;
	a = b;
	b = temp;

	cout << a << "\t" << b << endl;
}

int main()
{
   
	int a = 1, b = 2;
	myswap(a, b);

	double c = 1.3, d = 3.2;
	myswap(c, d);

	return 0;

}

1.3 自动类型推导与显式指定类型

在上面的例子中,我们定义完 a 和 b 后直接将其输入myswap() 的形参中去,事实上是编译器自动判断T的类型的,因此这种方式称为自动类型推导。

与自动类型推导相对的,是我们显式的去告诉编译器我们输入的实参的类型,其语法是:

//自动类型推导
myswap(a,b)
//显式指定类型
myswap<int>(a,b)

1.4 注意事项

  1. 自动类型推导,其数据类型必须一致;
  2. 模板必须确定T的数据类型才可以使用。

对于第一点,其实不完全对,或者说,仅在上面那种写法下是正确的。

template<typename T>
void myswap(T &a, T &b)
{
   
	/*******/
}

int main()
{
   
	int a = 10;
	char b = 'b';
	myswap(a,b);//这个时候编译器会报错,因为无法判断形参的类型
}

但是在下面的情况下是可以不一致的。

template<class T,class V>
void aaa(T &a, V &b)
{
   
	cout << a - b << endl;
}
int main()
{
   
	int a = 10;
	char b = 'a';
	aaa(a, b);//这样编译器就可以判断T是int类型,V是char类型了
	aaa<int,char>(a,b);//这样的写法也是被编译器认可的
}

对于第二点,它的含义是,在模板函数的实现中必须出现通用类型T。

template<class T>
void aaa()
{
   
	cout << "aaa()实现" << endl;
}
int main()
{
   
	aaa();//这个调用是会报错的,应为aaa的定义中没有出现T
	//这个所谓的出现不一定是在函数体内,只出现在形参列表也是可以的,反正得出现一次至少
}

1.5 与普通函数的区别

  1. 普通函数可以发生自动类型转换;
  2. 函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换
  3. 但是通过显式指定类型的方式,则可以发生隐式类型转换

另外说一句,在引用传递的时候不会发生隐式类型转换。

1.6 函数模板与普通函数的调用规则

  1. 在都能调用的情况下,优先普通函数
  2. 通过空模板参数列表强制调用函数模板
  3. 函数模板可以重载
  4. 如果函数模板可以产生更好的匹配,使用函数模板

在都能调用的情况下,优先普通函数

void myprint(int a)
{
   
	cout << "普通函数" << endl;
}

template<typename T>
void myprint(T a)
{
   
	cout << "模板函数" << endl;
}

/******主函数*******/
int a =10;
myprint(a);

在这种情况下两个都能调用,编译器选择优先调用普通函数。

通过空模板参数列表强制调用函数模板

/******主函数*******/
int a =10;
myprint<>(a);

这里利用空模板参数列表强制调用了模板函数。

函数模板可以重载

template<typename T>
void myprint(T a)
{
   
	cout << "模板函数" << endl;
}

template<typename T>
void myprint(T a,T b)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值