C++:函数模板详解

C++:函数模板详解

一、函数模板

#include <iostream>
using namespace std;

// 利用模板实现通用交换函数
// T代表通用的数据类型,告诉编译器下面紧跟着的函数出现T不要报错。
template <class T>
void userSwap(T& var01, T& var02)
{
	T tmp = var01;
	var01 = var02;
	var02 = tmp;
}


/*
模板函数调用方式:
    1、自动类型推导:实参列表中,T对应数据类型须一致;
    2、显式指定T实参类型
*/
int main()
{
	int a = 100;
	int b = 200;
	// 1、自动类型推导:实参列表中,T对应数据类型须一致;
	userSwap(a, b); // 实参a、b均为int型数据,函数可自行推导出T为int型数据类型。
	cout<<"a = "<<a<<endl; // a = 200
	cout<<"b = "<<b<<endl; // b = 100
    
	float c = 1.414;
	float d = 1.732;
	// 2、显式指定类型
	userSwap<float>(c, d); // 显式指定T为float数据类型,此时实参c、d亦须是float数据类型
	cout<<"c = "<<c<<endl; // c = 1.732
	cout<<"d = "<<d<<endl; // d = 1.414
    
    return 0;
}

二、模板不能单独使用,须指定T才可以使用。

#include <iostream>
using namespace std;

template <class T>
void func(){}


int main()
{
    // func(); // 模板不能单独使用,须指定T才可以使用。
    func<int>(); // 指定T的类型为int,可以正常调用    

    return 0;
}

三、函数模板和普通函数的调用规则

1、若函数模板与普通函数都可以调用,优先调用普通函数

2、若要强制调用函数模板,可使用空模板函数列表

3、函数模板可发生函数重载

4、若函数模板可产生更好的匹配,则优先调用函数模板

#include <iostream>
#include <string>
using namespace std;

template <class TYPE>
void userPrint(TYPE var01, TYPE var02)
{
	cout<<"函数userPrint(TYPE var01, TYPE var02)调用"<<endl;
}

// 模板函数发生重载
template <class TYPE>
void userPrint(TYPE var01, TYPE var02, TYPE var03)
{
	cout<<"函数userPrint(TYPE var01, TYPE var02, TYPE var03)调用"<<endl;
}

void userPrint(int var01, int var02)
{
	cout<<"普通函数userPrint(int var01, int var02)调用"<<endl;
}

int main()
{
    int a = 10;
	int b = 20;
	// a、若函数模板与普通函数都可以调用,优先调用普通函数
	userPrint(a, b); // 调用普通函数userPrint(int var01, int var02)
	// b、若要强制调用函数模板,可使用空模板函数列表
	userPrint<>(a, b); // 调用函数模板userPrint(TYPE var01, TYPE var02)
	// c、函数模板可发生函数重载
	userPrint(a, b, 10); // 调用函数模板userPrint(TYPE var01, TYPE var02, TYPE var03)
	// d、若函数模板可产生更好的匹配,则优先调用函数模板
	char c = 'c';
	char d = 'd';
	userPrint(c, d); // 调用函数模板userPrint(TYPE var01, TYPE var02)
    
    return 0;
}

四、函数模板实现机制

1、编译器并非将函数模板处理成可处理任何类型数据的函数;

2、函数模板通过具体的数据类型产生不同的函数,新生成的函数称为模板函数;

3、编译器会对函数模板进行两次编译。声明时对模板自身代码进行一次编译;在调用时对参数替换后的代码再进行一次编译。

五、函数模板的局限性

1、函数模板并不能对任意的数据类型进行操作(如自定义数据类型);

2、可利用具体化技术,实现对自定义数据类型提供特殊模板。template<> bool myCompare(const Person& a, const Person& b)

#include <iostream>
#include <string>
using namespace std;

class Person
{
public:
    string name;
	int age;
public:
	explicit Person(string name, int age)
	{
		this->name = name;
		this->age = age;
	}
};

// 不能对自定义的数据类型数据进行操作
template <class TYPE>
bool myCompare(const TYPE& a, const TYPE& b)
{
	return a == b;
}

// 利用具体化技术,实现对自定义数据类型提供特殊模板。
template<> bool myCompare(const Person& a, const Person& b)
{
	return (a.name == b.name && a.age == b.age);
}

int main()
{
	int a = 10;
	int b = 20;
	if(myCompare(a, b))
	{
		cout<<"a == b"<<endl;
	}
	else{
		cout<<"a != b"<<endl;
	}
	
	Person p1("Lisi", 20);
	Person p2("Lisi", 20);
	if(myCompare(p1, p2))
	{
		cout<<"p1 == p2"<<endl;
	}
	else{
		cout<<"p1 != p2"<<endl;
	}
    
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值