学习:模板

函数模板:

C++另一种编程思想称为泛型编程,主要利用的技术就是模板

C++提供两种模板机制:函数模板类模板


函数模板语法:

函数模板作用:

建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表。

语法:

template<typename T>

函数声明或定义

解释:

template --- 声明创建模板

typename --- 表面其后面的符号是一种数据类型,可以用class代替

T --- 通用的数据类型,名称可以替换,通常为大写字母

示例代码:

#include<iostream>

using namespace std;

template<typename T>
void mySwap(T& a, T& b) //利用传递的方式
{
	T temp = a;
	a = b;
	b = temp;
}

void test01() {
	//有两种种调用方式
	int a = 10;
	int b = 20;

	//第一种自动类型推导
	mySwap(a, b);

	//第二种调用方式
	mySwap<int>(a, b); //显示指定类型
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;

}

int main() {
	test01();
	system("pause");
	return 0;

}

总结:
1、函数模板利用关键字 template
2、使用函数模板有两种方式:自动类型推导显示指定类型
3、模板的目的是为了提高复用性,将类型参数化


函数模板注意事项:

1、自动类型推导,必须推导出一致的数据类型T,才可以使用

示例代码:

#include<iostream>

using namespace std;

template<typename T>
void Swap(T &a, T &b) {
	T temp;
	temp = a;
	a = b;
	b = temp;
}

void test01() {
	int a = 10;
	int b = 20;
	int c = 0.1;
	//Swap(a,b); //正确
	Swap(a, c);//错误
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;

}

int main() {
	test01();
	system("pause");
	return 0;
}

2、模板必须要确定出T的数据类型,才可以使用
示例代码:

#include<iostream>

using namespace std;

template<typename T>
void func() {
	cout << "this is test" << endl;
}

void test01() {
	// func(); 直接调用无法运行,我们必须要指定类型
	func<int>();
}

int main() {
	test01();
	system("pause");
	return 0;
}

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

大家记住三句话就可以了

1、普通函数调用时可以发生自动类型转换(隐式类型转换)
2、函数模板调用时,如果利用自动类型推导,不会发生隐式类型转换
3、如果利用显示指定类型的方式,可以发生隐式类型转换

#include<iostream>

using namespace std;

template<class T>
int test01(T a, T b) {
	return a + b;
	
}

int test02(int a,int b) {
	return a + b;
}

int main() {
	cout << test02(1, 2) << endl; //可以打印 
	cout << test02(1, 'a') << endl;//可打印 
	
	cout << test01(1, 2) << endl; //可以打印
        cout << test01('a','a') << endl; //可以打印
	//cout << test01(1, 'a') << endl; //不可以打印
	cout << test01<int>(1, 'a') << endl; //可以打印

	system("pause");
	return 0;

}

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

#include<iostream>

using namespace std;

void test01(int a,int b) {
	cout << "这是调用了普通函数" << endl;
}

template<class T>
void test01(T a, T b) {
	cout << "这是调用了函数模板" << endl;

}
template<class T>
void test01(T a, T b, T c) {
	cout << "这是调用了重载函数模板" << endl;
}



int main() {
	test01(1, 1); //优先调用普通函数
	test01<>(1, 1); //可以利用空模板的方式进行优先调用函数模板
	test01(1, 2, 3); //函数模板可以进行重载
	test01('a', 'b'); //函数模板如果可以产生更好的匹配,那么会优先调用函数模板
	system("pause");
	return 0;

}

总结:既然提供了函数模板,最好就不要提供普通函数,否则容易出现二义性


模板的具体化:

具体化的特点
1、具体化,显示具体化的原型和定意思以template<>开头,并通过名称来指出类型
2、具体化优先于常规模板

作用:当我们一个比较数值的函数模板,如果传入单个数值比较的话是可以的,但是如果我们传入的数值是一个数组,一个类的话那么就无法进行比较,C++为了解决这种问题,提供模板的重载,可以为这些特定的类型提供具体化的模板

示例代码:

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


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

template<class T>
bool Compare(T a, T b) {
	if (a == b) {
		return true;
	}else {
		return false;
	}
}
	
//具体化,显示具体化的原型和定意思以template<>开头,并通过名称来指出类型
//具体化优先于常规模板
template<> bool Compare(Person a, Person b) { //template<> 这种写法对Compare的函数模板进行模板具体化 传入的参数为Person,这里传入引用不引用其实都没关系,只是进行比较
	if (a.m_age == b.m_age) {
		return true;
	}else {
		return false;
	}
}

int main() {
	//int a = 1;
	//int b = 2;
	bool ret;
	//ret = f1(a, b);
	Person p1("adexx", 18);
	Person p2("adedd", 19);
	ret = Compare(p1, p2);
	if (ret) {
		cout << "true" << endl;
	}else {
		cout << "false" << endl;
	}
	system("pause");
	return 0;

}
原文地址:https://www.cnblogs.com/zpchcbd/p/11907836.html