为什么要有这玩意

泛型设计:算法不依赖数据结构

当交换两个变量值时,我们会这样写

// 项目中发现要交换两个int,于是写出了下面的代码
void swap(int & x, int & y)
{
    int t = x; 
    x = y;
    y = t;
}
// 有一个,又发现需要交换两个double,于是下面的代码应运而生
void swap(double & x, double & y) {
    double t = x; 
    x = y;
    y = t;
}

如果还是其他数据类型,那就需要写n的相似的函数

函数模板就是为了解决这个问题

template <class T>
void swap(T & x, T & y)
{
    T t = x; 
    x = y;
    y = t;
}
int main(){
    int a = 1;
    int b = 2;
    // 当你传入两个int变量时,编译器自动生成 void swap(int &, int &)函数
    swap(a, b); 
    
    double c = 1.1;
    double d = 2.2;
    // 当你传入两个double变量时,编译器自动生成 void swap(double &, double &)函数
    swap(c, d);
    return 0; 
}

定义

template<class 类型参数1, class 类型参数2, ... >
返回值类型 模板名 (形参表) {
    函数体
}

// 当函数中只存在一种变化的数据类型,或,只允许存在一种数据类型时,就像上面交换两个那样写
template <class T>
void swap(T & x, T & y)
{
    T t = x; 
    x = y;
    y = t;
}
// 当函数中可能存在多种变化的数据类型时,可以按照下面方式写
template <class T1, class T2>
void print(T1 & t1, T2 & t2) {
    cout << t1 << endl;
    cout << t2 << endl;
}
int main() {
    int a = 1;
    int b = 2;
    print(a, b); // 传递相同的数据类型
    double c = 3.3;
    print(a, c); // 传递两个不同的数据类型,都会调用同一个函数模板
}

函数模板重载

#include <iostream>
#include <stdio.h>

using namespace std;

template <class T1, class T2>
void print(T1 & t1, T2 & t2) {
    cout << "print(T1 & t1, T2 & t2)" << endl;
}

template <class T>
void print(T & t1, T & t2) {
    cout << "print(T & t1, T & t2)" << endl;
}

int main() {
    int a = 1;
    int b = 2;
    print(a, b);
    double c = 3.3;
    print(a, c);
}

哪个函数会被执行

当调用2个int的swap时,哪个会被执行

int a = 1;
int b = 2;
swap(a, b); 

1、 参数完全匹配的普通函数(非由模板实例化而得的函数)

void swap(int a, int b) {
    // ...省略
}

2、 参数完全匹配的模板函数

template <class T>
void swap(T a, T b) {
    // ...省略
}

3、 实参经过自动类型转换后能够匹配的普通函数

void swap(double a, int b) {
    // ...省略
}

4、 上面的都找不到, 则报错


熊一帆
96 声望14 粉丝