C++函数模板

95 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第24天,点击查看活动详情

1、函数模板

写一个两个整数的交换的函数,再写一个两个浮点型的数交换的函数,你会发现这两个函数除了数据类型不一样,其他的都一样,那么有没有什么办法让我们少些一边代码呢?答案就是函数模板:

#include <iostream>
using namespace std;
//函数模板
template <typename T>//T是一个通用的数据类型,只有在使用的时候才会被确定
void Swap(T &a, T &b)
{
	T temp = a;
	a = b;
	b = temp;
}
//类模板
int main()
{
	int a = 2, b = 3;
	Swap(a, b);//在这个里编译器会自动是识别出a,b为int类型的数据即自动类型推到
	cout << "a:" << a << endl;
	cout << "b:" << b << endl;
	double a1 = 3.14, b1 = 2.71;
	Swap<double>(a1, b1);//在函数名加一个<数据类型>就可以告诉编译器a1,b1的数据类型,即显示指定类型
	cout << "a1:" << a1 << endl;
	cout << "b1:" << b1 << endl;
}

image.png

2、重载的函数模板

函数模板也可以发生重载,两个函数具有相同的名称,参数列表的参数的类型、数量、顺序不同。

template <typename T>//T是一个通用的数据类型,只有在使用的时候才会被确定
void Swap(T &a, T &b,int n)
{//交换n次
	for(int i=0;i<n;i++){
            T temp = a;
            a = b;
            b = temp;
        }
}
int main()
{
	double a1 = 3.14, b1 = 2.71;
	Swap<double>(a1, b1,2);
	cout << "a1:" << a1 << endl;
	cout << "b1:" << b1 << endl;
}

image.png

3、模板你的局限性

在一个判断两个数是否相等的函数中,a==b;的语法是正确的(a,b为内置的数据类型如int),但是如果我们自定义的数据类型如 class Person {};Person p1,p2;这个时候p1==p2的语法是错误的,那么Person就不能使用上述的交换模板。

template <typename T>//T是一个通用的数据类型,只有在使用的时候才会被确定
bool Compare(T &a, T &b)
{
   if (a == b)
   	return true;
   else
   	return false;
}

class Person
{
public :
   int age;
   string name;
};
//类模板
int main()
{
   Person p1, p2;
   p1.age = 10; p1.name = "lisa";
   p2.age = 20; p2.name = "tom";
   Compare(p1, p2);
   
}

image.png 解决方法有两个,一是对"=="进行运算符重载;二是把模板具体化

class Person
{
public :
	int age;
	string name;
};
template <typename T>//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.age == b.age && a.name == b.name) {
		cout << "相同" << endl;
		return true;
	}
		
	else
	{
		cout << "不相同" << endl;
		return false;
	}
}
int main()
{
	Person p1, p2;
	p1.age = 10; p1.name = "lisa";
	p2.age = 20; p2.name = "tom";
	Compare(p1, p2);
}

image.png

4、普通函数与函数模板的区别

隐式类型转换:

int add(int a, int b)
{
	return a + b;
}
int main()
{
	int a = 2;
	char b = '3';
        //在调用add的时候,字符型变量传入的是'3'对应的ASCII码;
	cout << add(a, b) << endl;
}

image.png 这种隐式类型在普通函数中是可以发生的,在自动类型推导的函数模板中不会发生,但是在显示指定类型中会发生。

template <typename T>
T add(T a, T b)
{
	return a + b;
}
int main()
{
	int a = 2;
	char b = '3';
	cout << add<int>(a, b) << endl;
}

这段代码的运行结果依旧是53. 但如果是自定类型推导就会报错

image.png