模板——函数模板的基本语法和调用规则

1.模板函数

        1.1分为自动类型堆到和显示指定类型

template<class T>
void SwapNum(T &a, T &b)
{
	T temp = a;
	a = b;
	b = temp;
}

void test01()
{
	int a = 10;
	int b = 20;
	double c = 30.5;
	double d = 40.8;
	SwapNum(a, b);//自动类型推导
	SwapNum<int>(a, b);//显式指定类型
	SwapNum(c, d);
	cout << a << " " << b << " " << c << " " << d << endl;
}

2.注意事项

2.1自动类型推导必须推导出一致的类型T才可以使用

2.2模板必须要确定T的数据类型才可以使用

template<class T>
void SwapNum(T &a, T &b)
{
	T temp = a;
	a = b;
	b = temp;
}
template<class T>
void func()
{
	cout << "函数func的调用" << endl;
}
void test01()
{
	int a = 10;
	int b = 20;
	char c = 'c';
	SwapNum(a, b);//正确,可以推导出一致的类型数据
	//SwapNum(a, c);错误,推导不出一致的类型数据
}
void test02()
{
	//func();//不能直接调用函数模板
	func<int>();//要指定函数模板的参数才能调用
}

//函数模板案例——数组排序的函数模板

template<class T>
void SwapNum(T &a, T &b)
{
	T temp = a;
	a = b;
	b = temp;
}
template<class T>//排序数组的函数模板
void Sort(T arr[],int len)//选择排序
{
	for (int i = 0; i < len; i++)
	{
		int min = i;
		for (int j = i + 1; j < len; j++)
		{
			if (arr[j] < arr[min])
			{
				min = j;
			}
		}
		if (i != min)
		{
			SwapNum(arr[i], arr[min]);
		}
	}
}
template<class T>//打印数组的函数模板
void Print_Arr(T arr[], int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << " ";
	}
	cout << endl;
}
void test01()
{
	char arr1[] = "cabeidfgjh";
	int len = sizeof(arr1) / sizeof(char);
	Sort(arr1, len);
	Print_Arr(arr1, len);
}
void test02()
{
	int arr2[] = { 3,5,2,4,6,1,8,7,9 };
	int len = sizeof(arr2) / sizeof(int);
	Sort(arr2, len);
	Print_Arr(arr2, len);
}

3.普通函数与函数模板的区别

3.1普通函数调用时可以发生自动类型转换(隐式类型转换)

3.2函数模板在使用自动类型推导方式时,不会发生自动类型转换

3.3函数模板使用显示指定类型方式时,可以发生隐式类型转换

使用过程中建议使用显示指定类型方式,方便自己确定通用类型

int AddNum1(int a, int b)//普通函数
{
	return a + b;
}
template<class T>//函数模板
T AddNum2(T a, T b)
{
	return a + b;
}
void test01()
{
	int a = 10;
	int b = 20;
	char c = 'a';
	cout << AddNum1(a, c) << endl;//普通函数的隐式转换,a转为ASCII码值为97
	//cout << AddNum2(a, c) << endl;//自动推导型不能发生隐式转换
	cout << AddNum2<int>(a, c) << endl;//函数模板的指定类型方式可以
}

4.普通函数和函数模板的调用规则

4.1如果普通函数和模板函数都可以实现,优先使用普通函数(即使普通函数没有实现代码)

4.2可以通过空模板参数列表来强制调用函数模板

4.3函数模板也可以发生重载

4.4如果函数模板可以产生更好的匹配,优先调用函数模板

一般写了函数模板就不会再写普通函数,容易产生二义性

void Print(int a,int b)//普通函数
{
	cout << "调用的普通函数" << endl;
}
template<class T>//函数模板
void Print(T a,T b)
{
	cout << "调用的函数模板" << endl;
}

void test01()
{
	int a = 10;
	int b = 20;
	Print(a, b);//都可以实现,优先调用普通函数
	Print<>(a, b);//可以通过空模板参数列表来强制调用函数模板
	char c = 'c';
	char d = 'd';
	Print(c,d);//如果函数模板可以产生更好的匹配,优先调用函数模板
}

5.模板的局限性

template<class T>
void func(T& a, T& b)
{
	a = b;//如果传入的是数组,就无法实现赋值操作
}

template<class T>
bool Compare(T &a, T &b)//如果传入的是自定义类型就无法比较了
{
	if (a == b)
	{
		return true;
	}
	else
	{
		return false;
	}
}

5.1利用具体化的模板,可以解决自定义类型的通用化

5.2学习模板不是为了自己写模板,而是为了在STL中使用系统提供的模板

class Person
{
public:
	Person(string name,int age)
	{
		this->m_name = name;
		this->m_age = age;
	}
	string m_name;
	int m_age;
};
template<class T>
bool Compare(T &a, T &b)//比较不了自定义类型
{
	if (a == b)
	{
		return true;
	}
	else
	{
		return false;
	}
}
template<>bool Compare(Person& a, Person& b)//利用具体化的Person的版本实现代码,具体化优先调用
{
	if (a.m_name == b.m_name && a.m_age == b.m_age)
	{
		return true;
	}
	else
	{
		return false;
	}
}
void test01()
{
	int a = 10;
	int b = 10;
	if (Compare(a, b))
	{
		cout << "a==b" << endl;
	}
	else
	{
		cout << "a!=b" << endl;
	}
	Person p1("Tom", 10);
	Person p2("Tom", 10);
	if (Compare(p1, p2))
	{
		cout << "p1==p2" << endl;
	}
	else
	{
		cout << "p1!=p2" << endl;
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值