0
点赞
收藏
分享

微信扫一扫

初识及C++模板,总结函数模板的特点以及具体使用

kmoon_b426 2022-07-12 阅读 59

世间皆苦,唯有自度

✨引言


✨目录

模板

函数模板

函数模板的使用

代码演示

函数模板的排序案例

代码实现

运行效果

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

代码演示

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

代码演示

模板的局限性

代码示例

✨总结 


模板

        我们都知道C++有一种编程思想是面向对象编程,这个在我的C++入门专栏已经系统学习过。而C++另一种编程思想就是泛型编程,主要利用的技术就是模板。

函数模板

函数模板的使用

代码演示

template<typename T>
void mySwap(T& a, T& b)
{
	T t = a;
	a = b;
	b = t;
}
void test01()
{
	int a = 10, b = 20;
	mySwap<int>(a,b);//显示
	double c = 3.4, d = 6.8;
	mySwap(c, d);//自动类型推导
	cout << "a=" << a << "b=" << b << endl;
	cout << "c=" << c << "d=" << d << endl;
}

        通过mySwap交换函数模板可以给整型和浮点型的数据进行交换,自动推导或者显示指定类型都会让T变为对应的数据类型 。自动类型推导的时候参数列表的数据类型要一致,例如:

        同样的函数模板调用,自动类型推导的方式会显示没有“与参数列表匹配的函数模板的错误”,因此使用函数模板的时候要注意这一点。

函数模板的排序案例

        趁热打铁,来一个小案例练练手吧!做一个升序排序,可以适用不同类型的数组,这里就测试整型和字符型的数组。

代码实现

//函数模板排序案例,选择排序的升序
template<class T>
void mySort(T arr[], int len)
{
	for (int i = 0; i < len - 1; i++)
		for (int j = i + 1; j < len; j++)
		{
			if (arr[j] < arr[i])
			{
				T temp = arr[i];
				arr[i] = arr[j];
				arr[j] = temp;
			}
		}
	cout << "升序排序成功!" << endl;
}
void test02()
{
	int arr[5] = { 2,5,3,4,1 };
	int len = sizeof(arr) / sizeof(arr[0]);
	mySort(arr, len);
	cout << "排序后数组为:" << endl;
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << " ";
	}
}
void test02q()
{
	char arr[6] = {'v','s','b','a','B','A'};
	int len = sizeof(arr) / sizeof(arr[0]);
	mySort(arr, len);
	cout << "排序后数组为:" << endl;
	for (int i = 0; i < len; i++)
	{
		cout << arr[i] << " ";
	}
}
int main(void)
{
	test02();
	cout << "\n------------" << endl;
	test02q();
}

运行效果

         这里可以看到整型和字符型的数组都能通过调用函数模板来实现升序排序

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

代码演示

//测试案例
void testPrint(int a)
{
	cout << "普通函数的调用" << endl;
}
template<class T>
void testPrint(T a)
{
	cout << "函数模板的调用" << endl;
}
//重载函数模板
template<class T>
void testPrint(T a,T b)
{
	cout << "重载函数模板的调用" << endl;
}
void test04()
{
	testPrint(10);
	testPrint<>(10);//空模板参数列表<>
	testPrint<>(10, 20);
	char a = 'a';
	testPrint(a);/*这里理论上可以调用个普通函数以及函数模板,但是普通函数调用需要编译器隐式转换
	编译器认为不如直接自动推导 T 为char数据类型,所以函数模板产生了更好的匹配,调用了函数模板*/
}

运行效果:

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

代码演示

//加法测试
int addTest(int a, int b)
{
	return a + b;
}
template<class T>
int addT(T a,T b)
{
	return a + b;
}
void test03()
{
	int a = 10, b = 20;
	char ch = 'A';
	cout << addTest(a, ch)<<endl;
	//cout << addT(a, ch) << endl;
	cout << addT<int>(a, ch) << endl;
}

         test03中的三个cout语句,中间的cout会出现错误,证明了函数模板和普通函数的区别

模板的局限性

        模板并不是万能的,并不是任何情况下通用性都成立

代码示例

//模板的局限性
class Person
{
public:
	Person(string name, int age)
	{
		this->name = name;
		this->age = age;
	}
	string name;
	int age;
};
//模板并不是万能的,有些特定的数据类型,需要用具体化方式做特殊实现
//对比两个数据是否相等
template<class T>
bool myCompare(T& a, T& b)
{
	if (a == b)
	{
		return true;
	}
	else
	{
		return false;
	}
}
//利用具体化Person的版本来实现代码,具体优化优先调用
template<>bool myCompare(Person& p1, Person& p2)
{
	if (p1.name == p2.name && p1.age == p2.age)
	{
		return true;
	}
	else
	{
		return false;
	}
}
void test05()
{
	int a = 10;
	int b = 20;
	bool ret = myCompare(a, b);
	if (ret)
	{
		cout << "相等" << endl;
	}
	else
	{
		cout << "不相等" << endl;
	}
}
void test06()
{
	Person p1("Tom", 10);
	Person p2("Tom", 10);
	bool ret = myCompare(p1, p2);
	if (ret)
	{
		cout << "相等" << endl;
	}
	else
	{
		cout << "不相等" << endl;
	}
}
int main(void)
{
	test05();
	test06();
	return 0;
}

运行效果:

总结 

       利用具体化的模板可以解决自定义类型的通用性问题,其次强调一下学习模板是为了使用别人的模板,提高编程效率。像后面的STL内容的基础就是模板,所以需要打下牢固的基础。为了深层次的学习C++,一起奋斗吧,码文不易,求个三连~

举报

相关推荐

0 条评论