当先锋百科网

首页 1 2 3 4 5 6 7

函数模版

笔记来源 : 黑马程序员

语法

template<typename  T>
声明创建模板<typename 数据类型>
//typename可以用class代替T通常是大写字母
//模板必须要确定出T的数据类型,才可以使用

示例

//函数模板

template<typename T> //声明一个模板, 后面紧跟着使用它
void mySwap(T& a, T& b){
    T temp = a;
    a = b;
    b = temp;
}

void test(){
    int a = 10, b = 20;
    double c = 1.23, d = 3.23;
    //用函数模板实现交换
    //两种方式交换
    //1.自动类型推导, 必须推导出一致的 数据类型T,才可以使用
    mySwap(a, b);
    mySwap(c, d);
    //2.显式指定类型
    mySwap<int>(a, b);
    mySwap<double>(c, d);
}

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

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

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

//以下情况优先调用普通函数

void swap(int& a, int& b){
    int temp = a;
    a = b;
    b = temp;
}

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

//以下情况优先调用普通函数
//报错 :无法解析的外部命令, 在链接阶段出现问题,找不到函数的实现体
void swap(int& a, int& b);

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

//可以通过空模板参数列表, 强制调用函数模压板
//在调用的时候写   MySort<>(a, b)

//以下这种情况调用模板
void mySort(int a, int b){
    int t = a;
    a = b;
    b = t;
}

template<class T>
void mySort(T a, T b){
    T t = a;
    a = b;
    b = t;
}

void test(){
    char a = 'a', b = 'b';
    mySort(a, b);
}

模板的局限性

有些特定的数据类型需要用具体化的方式做特殊实现, 比如自定义数据类型

//比较两个类是否相等
//1. 重载 == 运算符 (比较麻烦)
//2. 利用具体化Person的版本实现代码

//1. 重载 == 运算符 (比较麻烦)

class Person {
public:
	bool operator==(Person p) {
		return (this->m_Age == p.m_Age && this->m_Name == p.m_Name);
	}

	Person(string  n, int a) : m_Age(a), m_Name(n) {}
	string m_Name;
	int m_Age;
};

template<class T>
bool compare(T p1, T p2) {
	return p1 == p2;
}

void test() {
	Person p1("123", 12);	
	Person p2("123", 12);

	cout << compare(p1, p2) << endl;
}

//2. 利用具体化Person的版本实现代码
class Person {
public:
    Person(string  n, int a) : m_Age(a), m_Name(n) {}
    string m_Name;
    int m_Age;
};

template<class T>
bool myCompare(T& p1, T& p2) {
    return p1 == p2;
}

template<> bool myCompare(Person& p1, Person& p2)
{
    if (p1.m_Age == p2.m_Age && p1.m_Name == p2.m_Name)
        return true;
    return false;
}

void test() {
    int a = 0, b = 0;
    cout << myCompare(a, b) << endl;
    Person p1("123", 12);
    Person p2("123", 12);

    cout << myCompare(p1, p2) << endl;
}