C++ 函数模板(2)普通函数与函数模板区别、普通函数与函数模板调用规则、以及模板的局限性

C++ 函数模板(2)

昨天刚整理了C++ 函数模板(1),今天同样要坚持哦 ,今天来继续的整理记录C++函数模板的笔记。今天主要整理——普通函数与函数模板区别、普通函数与函数模板调用规则、以及模板的局限性。废话不多说,冲!

05 普通函数与函数模板的区别
1、普通函数调用时可发生自动类型转换(隐式类型转换)
2、函数模板,自动类型推导,不可以发生隐式类型转换。
3、函数模板、用显示指定类型,可以发生隐式类型转换。
具体代码实现如下:

#include<iostream>
using namespace std;
//普通函数 减法
int  Sub(int a,int b)
{
    
    
	return(a-b);

}

//写一个模板函数
template<class T>
T Sub01(T a,T b)
{
    
    
     return (a-b);
}

//写一个输出函数
void test01()
{
    
    
    int a=100;
	int b=200;
	char c= 'c';

	cout<<Sub(a,c)<<endl;
	//自动类型推导输出
	//cout<<Sub01(a,c)<<endl; 自动类型推导不可以发生隐式类型转换
	//显示指定类型
	cout<<Sub01<int>(a,c)<<endl;
}

int main()
{
    
    
	test01();

system("pause");
return 0;
}

注意:建议使用显示指定类型的方式,调用函数模板,因为自己确定通用类型T。

06 普通函数与函数模板调用规则
1、如果函数模板和普通函数都可以实现,优先调用普通函数。
2、可以通过空模板参数列表来强制调用函数模板。
3、函数模板也可以发生重载。
4、如果函数模板可产生更好的匹配,优先调用函数模板。

#include<iostream>
using namespace std;
//1、如果函数模板和普通函数同时调用,则优先调用普通函数

//先来一个普通函数
void myfunc(int a,int b)
{
    
    
cout<<"This is ordinary func"<<endl;
}

//再来一个模板函数
template<typename T>
void myfunc(T a,T b)
{
    
    
cout<<"This is 模板函数"<<endl;

}

//再来一个函数重载
template<typename T>
void myfunc(T a,T b,T c)
{
    
    
cout<<"This is 重载模板函数"<<endl;

}

//写一个输出函数
void test01()
{
    
    
int a=10;
int b=20;
//myfunc(a,b);

//通过空模板参数列表来,强制调用函数模板
//myfunc<>(a,b);

//函数重载的调用
//myfunc<>(a,b,0);

//如果函数模板可以产生更好的匹配,优先调用函数模板
char c1='a';
char c2='b';

myfunc<>(c1,c2);//这是因为,输入的是字符,如果是调用普通函数需要进行隐式转换,即把字符转换为int数字,而调用模板的只用推导出T即可不用进行转换。
}**加粗样式**
//模板的话自动类型推导,不可以发生隐式类型转换。显示指定类型的话可以发生隐式转换。

int main()
{
    
    

	test01();

system("pause");
return 0;
}

注意:提供函数模板,不要写普通函数,避免二义性。

07 模板局限性
模板的通用性并不是万能的,有些特定数据类型,需要用具体化方式做特殊实现如bool数据类型调用,以及Person等一些自定义数据类型。
函数案例测试如下:

#include<iostream>
using namespace std;
#include<string>
//函数的局限性,函数的通用性不是万能的
//有些特定的数据类型需要用具体话的方式来实现
//整一个自定义数据类型的对比
class Person
{
    
    
public:
	Person(string name,int age)
	{
    
    
		this->m_name=name;
		this->m_age=age;
	}

//姓名
string m_name;
//年龄
int m_age;
};

//1、比较两个数据的大小
template<class T>
bool Contrast(T &a,T &b)
{
    
    
if(a==b)
{
    
    
return true;
}
else
{
    
    
return false;
}

}

//利用具体化Person的版本实现代码,具体化优先调用
template<> bool Contrast(Person &p1,Person &p2)
{
    
    
	if(p1.m_name == p2.m_name && p1.m_age==p2.m_age)
	{
    
    
	return true;
	}
	else
	{
    
    
	return false;
	}

}

//写一个测试输出函数
void test01()
{
    
    
int a=10;
int b=20;

bool ret=Contrast(a,b);
if(ret)
{
    
    
cout<<"a==b"<<endl;
}
else
{
    
    
cout<<"a!=b"<<endl;
}
}

//再写一个自定义类的输出函数
void test02()
{
    
    
Person p1("wjx",20);
Person p2("wjx",20);

bool ret=Contrast(p1,p2);
if(ret)
{
    
    
cout<<"p1==p2"<<endl;
}
else
{
    
    
cout<<"p1!=p2"<<endl;
}
}
int main()
{
    
    
	test01();
	test02();

system("pause");
return 0;
}

注意:
1、字符是如何定义的char c1=‘a’; char c2=‘b’。
2、Person\Class等类在最后要加;如果不加;会有意想不到的报错哦。
3、利用具体化模板,可以解决自定义类型的通用化。
4、学习模板并不是为了写模板,而是在STL能够运用系统提供的模板来满足我们的需要。

猜你喜欢

转载自blog.csdn.net/qq_45252077/article/details/107895214