c++模板 --- 函数模板

什么是模板?

把类型当做未知量来处理的行为叫做模板 写的函数或者类,不因为数据类型的改变,而要修改代码--->数据类型改变,依然适用于原来的代码(代码功能依旧可以使用)

  • 忽略类型的影响

  • 求(int类型、string类型...)最大值

  • 因为数据类型的不同,需要写多个相同的函数--->虽然函数体是一样的,但是类型不同导致的额外代码

//求int类型的最大值
int Max(int a,int b)
{
    return a > b ? a : b;
}
//求string类型的最大值
string Max(string a,string b)
{
    return a > b ? a : b;
}

声明模板的语法 template <typename _Ty>

引入模板,把类型当作未知量

? Max(? a,? b)         //引入模板 把类型当作未知量 未知类型|未知参数|函数体相同

template <typename _Ty>//template告诉编译器下面代码用到了一个未知类型_Ty 把_Ty当作类型去用
_Ty Max(_Ty a, _Ty b)  //typename可以换成class
{
	return a > b ? a : b;
}

存在单个未知类型 

//单个未知类型
template <typename _Ty>	   //固定语法
_Ty Max(_Ty a, _Ty b)      //_Ty:未知类型  a & b:未知参数    
{
	return a > b ? a : b;  //函数体一样
}

template <typename _Ty> _Ty Max(_Ty a, _Ty b) 
        //或
template <typename _Ty>	   
_Ty Max(_Ty a, _Ty b) 

/*两种都可以 第二种情况更美观
  _Ty 随便改,就是类型代号*/

 对于函数来说可以存在单个未知类型,也可以存在多个未知类型

//多个未知类型
template <typename _Ty1,typename _Ty2 >    //存在多个未知类型 用 , 做间隔
void print(_Ty1 one,_Ty2 two)              //如果还需要返回值可以_Ty3
{
	cout<< one << endl;
    cout<< two << endl;
}
int main()
{
//传两个一样的类型
    print<string, string>("string1", "string2");
//传不同的类型
	print<string, int>("string1", 1234);
}
/*输出*/

string1
string2
string1
1234

调用函数模板

调用函数模板 ---> 一个函数写了多个函数的功能,不因为类型的改变,需要把函数重写

  • 隐式调用:正常的函数传参即可调用,不用管数据类型--->不需要显式传参

  • 显示调用:函数名<类型名>(参数) ---> 需要显式传参

  • 常用的函数 & 函数体相同的函数,一般使用函数模板来做

隐式调用

template <typename _Ty>	   
_Ty Max(_Ty a, _Ty b)    
{
	return a > b ? a : b;  
}

int main()
{
//隐式调用
	cout << Max(1, 2) << endl;
	cout << Max("string", "string1") << endl;
	cout << Max(1.1, 2.3) << endl;
}
/*输出*/

2
string
2.3

显式调用

  • 显式传入类型,遵守函数调用的规定,实参与形参类型一致

template <typename _Ty>	   
_Ty Max(_Ty a, _Ty b)    
{
	return a > b ? a : b;  
}

int main()
{
//显示调用 传入string类型 加两个string类型参数即可
	cout << Max<string>("abc","abd") << endl;
}

/*输出*/

abd

/*传参过程|默认传入3个参数*/

_Ty = string
a = "abc"
b = "abd"

两个未知类型的显示调用 

template <typename _Ty1,typename _Ty2 >    
void print(_Ty1 one,_Ty2 two)              
{
	cout << one << endl;
    cout << two << endl;
}
int main()
{
//传入两个一样的类型
    print<string,string>("string1","string2");
//传入不同的类型 模板传什么类型,参数也要与之匹配
    print<string,int>("string1",1234);
}

/*输出*/

string1
string2
string1
1234

函数模板的两种形态

  • 普通函数当做函数模板(上面的代码已经证实)

  • 类的成员函数是函数模板(用法和普通函数一样)

 类的成员函数是函数模板

class MM 
{
public:
	template <class _Ty>         //类中的成员函数是函数模板和普通函数用法一样
	void print(_Ty data) 
	{
		cout << data << endl;
	}
protected:
	string name;
	int age;
};
int main()
{
	MM mm;                        //构造一个对象调用
	mm.print(123);                //隐式调用
	mm.print<string>("ILoveyou"); //显式调用
}
/*输出*/

123
ILoveyou

类的成员函数的方式可以在类中声明,在类外实现,在类外实现不能省略 template 这一块

class MM 
{
public:
	template <class _Ty>
	void printData(_Ty data);
protected:
	string name;
	int age;
};

//在类外实现不能省略template这一块
template <class _Ty>
void MM::printData(_Ty data) 
{
	cout << data << endl;
}

int main()
{
    MM mm;
    mm.printData(12344);
}
/*输出*/

12344

函数模板特殊的写法

  • 函数模板与函数传参一样,可以缺省处理

  • 存在常量类型  

函数模板缺省

template <class _Ty1, class _Ty2 = int>	//缺省为int类型
void printData(_Ty1 one, _Ty2 two)
{
	cout << one << "\t" << two << endl;
}
void testFunc()
{
	printData("string", 1234);           //隐式调用无明显区别
    printData<string>("ILoveyou", 12344);//函数模板缺省显式调用 可以不传类型但参数不能少
}
int main()
{	
	testFunc();
	return 0;
}

/*输出*/

string  1234
ILoveyou        12344
//如果只传一个参数,如果第2个参数不传默认int类型,要传int类型的参数进去

存在传常量类型

/*存在传常量写法
  int 或 size_t    size_t: unsigned int 的别名(无符号整型) */

//打印数组(不同类型的)数组,传长度的参数
template <class _Ty1 ,size_t size=3>  //做缺省,可以隐式调用                  
void printArray(_Ty1 array)		      //_Ty1 = int * 数组地址,size=3
{
	for (int i = 0; i < size; i++)    //声明1个变量size,意味着可以在函数里面使用这个变量
	{
		cout << array[i];
	}
	cout << endl;
}

void testFunc() 
{
    //函数模板中写了变量 没有做缺省必须显示调用
	int testarray[3] = { 1,2,3 };
	printArray<int*,3>(testarray);
	//没有做缺省必须显式调用,做了缺省可以隐式调用
	printArray(testarray);
	/*函数模板不能传入变量,只能传入常量
	int size = 3;
	printArray<int*, size>(testarray); 传入会报错 */
}
int main()
{
	testFunc();
}

/*输出*/

123
123
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qiuqiuyaq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值