函数模板与重载时的调用规则

对于这种 1.函数的业务逻辑一样 2.函数的参数类型不一样 的多次重复型函数,为了节省开发工作,提出泛型编程
泛型编程:即用template定义一个泛型T,用它来统代类型
全文内容包括以下几点:
1.泛型函数的基础
2.函数模板的强化(数组的泛型应用)
3.函数模板与函数重载
4.函数模板云函数重载相遇时的调用规则

1.泛型函数的基础
1.1函数模板分为显示调用和隐式调用,即主动地声明模板函数接收参数类型和传入参数时模板自动匹配,推荐显示调用

#include "iostream"
using namespace std;
void change01(int &a, int &b)//普通函数
{
	int c;
	c = a;
	a = b;
	b = c;
}
void change02(char &a, char &b)
{
	char c;
	c = a;
	a = b;
	b = c;
}
template <typename T>//函数模板的定义
void change03(T &a, T &b)
{
	T c;
	c = a;
	a = b;
	b = c;
}
void main01()
{
	{
		//int 类型的调用,现在要求交换char类型(必须重写change函数)
		int a = 10;
		int b = 20;
		change01(a, b);
		cout << "a=" << a << "   b=" << b << endl;
	}
	{
		char x = 'x';
		char y = 'y';
		change02(x, y);
		printf("a=%c    b=%c\n", x, y);
		cout << "x=" << x << "    y=" << y << endl;
	}
}
//函数模板的调用
// 显示类型 调用
// 自动类型 推导
void main02()
{
	{
		int a = 10;
		int b = 20;
		change03<int>(a, b);//1. 显示类型 调用  (就是函数后面,参数列表前面用<>显示参数类型)
		cout << "a=" << a << "   b=" << b << endl;
		change03(a, b);//2. 自动类型 推导
		cout << "a=" << a << "   b=" << b << endl;
	}
	{
		char x = 'x';
		char y = 'y';
		change03<char>(x, y);//1. 显示类型 调用
		cout << "x=" << x << "    y=" << y << endl;
		change03(x, y);//2. 自动类型 推导
		cout << "x=" << x << "    y=" << y << endl;
	}
}

2.函数模板的强化(数组的泛型应用)
2.1可以同时定义两个函数模板,使用时必须声明两个模板的类型

#include "iostream"
using namespace std;
template <typename T>
void mysort(T array[],T size)
{
	for (int i = 0; i < size; i++)
	{
		for (int j = i + 1; j < size; j++)
		{
			if (array[i] < array[j])
			{
				T tmp = array[i];
				array[i] = array[j];
				array[j] = tmp;
			}			
		}
	}
}
template <typename T,typename T2>//可以同时定义两个函数模板
void print(T array[],T2 size)
{
	for (int i = 0; i < size; i++)
	{
		cout << array[i] << ",";
	}
	cout << endl;
}
void main03()
{
	// int类型
	{
		int array[] = { 132,132,456,4,68465,464,6546,435,4864,4,864,6546,4 };
		int size = sizeof(array) / sizeof(array[0]);
		mysort<int>(array, size);
		print<int, int>(array, size);
	}
	//char 类型
	char buf[] = "qwertyuiopasfhadbvebv16469846";
	int size = sizeof(buf) / sizeof(char);
	mysort<char>(buf, size);//这样是不规范的,这样会将size转换成char类型
	print<char, int>(buf, size);
}

3.函数模板与函数重载
3.1普通函数可以进行隐式的参数转换,但是函数模板必须严格的匹配不会进行自动类型转换

#include "iostream"
using namespace std;
template <typename T>
void myswap(T &a, T &b)
{
	T c = 0;
	c = a;
	a = b;
	b = c;
	cout << "我是模板函数" << endl;
}
void myswap(int a, char c)//函数重载
{
	cout << "a:" << a << "c:" << c ;
	cout << "我是普通函数" << endl;
}
void main04()
{
	int		a = 10;
	char	c = 'z';
	myswap(a, c); // 普通函数的调用
	myswap(c, a); //普通函数的调用:  可以进行隐式的类型转换 
	myswap<int>(a, a); // 函数模板函数的调用(本质:类型参数化): 将严格的按照类型进行匹配,不会进行自动类型转换.
}

4.函数模板云函数重载相遇时的调用规则
4.1 函数模板可以像普通函数一样被重载
4.2 C++编译器优先考虑普通函数
4.3 如果函数模板可以产生一个更好的匹配,那么选择模板
4.4 可以通过空模板实参列表的语法限定编译器只通过模板匹配

#include "iostream"
using namespace std;
int Max(int a, int b)
{
	cout << "int Max(int a, int b)" << endl;
	return a > b ? a : b;
}

template<typename T>
T Max(T a, T b)
{
	cout << "T Max(T a, T b)" << endl;
	return a > b ? a : b;
}

template<typename T>
T Max(T a, T b, T c)//模板函数重载
{
	cout << "T Max(T a, T b, T c)" << endl;
	return Max(Max(a, b), c);
}

void main05()
{
	int a = 1;
	int b = 2;

	cout << Max(a, b) << endl; //当函数模板和普通函数都符合调用时,优先选择普通函数
	cout << Max<>(a, b) << endl; //若强制使用函数模板,则显示使用空 <> 类型列表

	cout << Max(3.0, 4.0) << endl; //如果 函数模板产生更好的匹配 使用函数模板
	//在普通函数的形参列表为int类型,但是传递的实参是double型,为避免参数失真,选择模板函数匹配

	cout << Max(5.0, 6.0, 7.0) << endl; //重载

	cout << Max('a', 100) << endl;  //调用普通函数 可以隐式类型转换 
	system("pause");
	return;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值