c++ 模板

1.泛型编程:(1)与类型无关  (2)通用   (3)任意场景都可处理  

2.模板:是泛型编程的基础。与类型无关

3.函数模板:

(1)该函数与类型无关,在使用时被参数化,根据参数类型产生函数的特定类型版本。

template <typename T>
T Add(T a, T b)
{
	return a + b;
}

int main()
{
	Add(1, 2);
	Add(1.0, 2.0);
	Add('1', '2');
	return 0;
}

此时就写了一个函数模板,与类型无关。

这里的typename也可写出class, T就是类型。

注意:这里可以用class但是不可以用struct。也就是说,模板参数列表只能用class。

(2)原理:

模板并不是函数,是编译器生成代码的规则

转到汇编代码看到,这里调用的函数是:Add<int>...,

所以说模板并不是函数,而是通过模板来推演出我们所需类型的函数。

假如参数类型不一致,编译器不会做类型转化。(自己可以进行隐式转化)

(3)参数模板的实例化:

模板参数的实例化分为两种:隐式转化和显示实例化

隐式实例化:编译器自动识别参数类型并推演成一个实例

	Add<int>(1, 2);

显示实例化: 直接命令编译器创建指定类型的函数实例。

	Add<int>(1, 2);

但是内部有可能做隐式转化

Add<int>(1, '2')

(4)函数模板参数的匹配规则

   1)一个非模板函数可以和一个同名的函数模板同时存在,而且该函数模板还可以被实例化为这个非模板函数

   2)对于非模板函数和同名函数模板,若其他条件相同,在调用的时候会优先调用非模板函数而不会从该模板产生一个实例。如果模板可以产生一个具有更好匹配的函数,那么选择模板。

int Add(int a, int b)
{
	return a + b;
}
template <typename T1,typename T2>
T1 Add(T1 a, T2 b)
{
	return a + b;
}

int main()
{
	Add(1, 2);
	Add(1, '2');
	Add(1.0, 2.0);
	Add('1', '2');
	return 0;
}

对于 1)为什么两个可以同时存在,是因为两个函数并不会冲突。一个函数名是Add  ,一个函数名是Add<>

对于2) 此时第一个Add就会调用自己写的函数。 对于第二个Add就会去调用自己写的,虽然调自己的可以做类型提升,但是调用模板的更合适.

3)显示指定一个空的模板实参列表,该语法告诉编译器只有模板才能来匹配这个调用,而且所有的模板参数都应该根据实参来演绎出来

Add<>(1, 2);

4)模板函数不许与自动的类型转换,但是普通函数可以进行自动类型转换。

Add(1, '2');

只有在显示实例化的时候,模板才可能在内部做类型转换

问题:下面比较的模板可以比较字符串吗?

template<class T>
T Max(const T& left, const T& right)
{
	return (left > right) ? left : right;
}
int main()
{
	char *a = "ebc";
	char *b = "cba";
	cout << Max(a, b) << endl;
	return 0;
}

发现结果是错的。此时他的比较规则是地址。所以对于自定义类型模板可能不可处理,将其方法进行重写写一下。

const char* Max(const char* left, const char* right)
{
	if (strcmp(left, right) > 0)
		return left;
	return right;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值