函数模板的概念和意义

发散性问题

C++中有几种交换变量的方法?

定义宏代码块 VS 定义函数

编程实验

#include <iostream>
#include <string>

using namespace std;

#define SWAP(t,a,b)  \
do                   \
{                    \
    t c = a;         \
    a = b;           \
    b = c;           \
}while(0)

int main()
{
    int a = 1;
    int b = 2;
    SWAP(int, a, b);

    cout << "a=" << a << endl;
    cout << "b=" << b << endl;

    double m = 3;
    double n = 5;
    SWAP(double, m, n);

    cout << "m=" << m << endl;
    cout << "n=" << n << endl;

    return 0;
}

利用定义宏代码块的方法看上去很完美,但是宏是预处理器处理的程序单元,后续出场的编译器根本不知道宏的存在,因此不推荐用宏来完成类似函数的功能。因为不安全。

直接定义函数

#include <iostream>
#include <string>

using namespace std;

void Swap(int& a, int& b)
{
    int c = a;
    a = b;
    b = c;
}

void Swap(double& a, double& b)
{
    double c = a;
    a = b;
    b = c;
}

void Swap(string& a, string& b)
{
    string c = a;
    a = b;
    b = c;
}

int main()
{
    int a = 1;
    int b = 2;
    Swap(a, b);

    cout << "a=" << a << endl;
    cout << "b=" << b << endl;

    double m = 3;
    double n = 5;
    Swap(m, n);

    cout << "m=" << m << endl;
    cout << "n=" << n << endl;

    string s1 = "hello";
    string s2 = "world";
    Swap(s1,s2);

    cout << "s1=" << s1 << endl;
    cout << "s2=" << s2 << endl;
    return 0;
}

定义宏代码块
-优点:代码复用,适合所有的类型
-缺点:编译器不知道宏的存在,缺少类型检查

定义函数
-优点:真正的函数调用,编译器对类型进行检查
-缺点:根据类型重复定义函数,无法代码复用

泛型编程
-不考虑具体数据类型的编程方式
对于Swap函数可以考虑下面的泛型写法
void Swap(T& a, T& b)
{
  T t = a;
  a = b;
  b = t;
}
Swap泛型写法中的T不是一个具体的数据类型,而是泛指任意的数据类型

函数模板
C++中泛型编程
-函数模板
  一种特殊的函数可用不同类型进行调用
  看起来和普通函数很相似,区别是类型可被参数化
template <typename T>
void Swap(T& a, T& b)
{
  T t = a;
  a = b;
  b = t;
}

函数模板的语法规则
-template关键字用于声明开始进行泛型编程
-typename关键字用于声明泛指类型

template告诉编译器开始泛型编程
typename T 告诉编译器T是一个泛指类型

函数模板的使用
-自动类型推导调用
-具体类型显示调用
int a = 0;
int b = 1;
Swap(a,b) //自动推导

float c = 2;
float d = 3;
Swap<float>(c,d); //显示调用

函数模板初探:

#include <iostream>
#include <string>

using namespace std;


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

int main()
{
    int a = 1;
    int b = 2;
    Swap(a, b);  //等价于Swap<int>(a,b)

    cout << "a=" << a << endl;
    cout << "b=" << b << endl;

    double m = 3;
    double n = 5;
    Swap(m, n); //等价于Swap<double>(m,n)

    cout << "m=" << m << endl;
    cout << "n=" << n << endl;

    string s1 = "hello";
    string s2 = "world";
    Swap<string>(s1,s2);  //等价于Swap(s1,s2)

    cout << "s1=" << s1 << endl;
    cout << "s2=" << s2 << endl;
    return 0;
}
#include <iostream>
#include <string>

using namespace std;


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

template<typename T>
void sort(T a[], int len)
{
    for(int i=0;i<len; i++)
    {
        for(int j=i; j<len; j++)
        {
            if(a[i] > a[j])
            {
                Swap(a[i],a[j]);
            }
        }
    }
}

template<typename T>
void println(T a[],int len)
{
    for(int i=0; i<len; i++)
    {
        cout << a[i] << ",";
    }
    cout << endl;
}
int main()
{
    int a[]={5,3,2,4,1};
    println(a,5);
    sort(a,5);
    println(a,5);

    string s[]={"Java","C++","Ruby","Pascal","Basic"};
    println(s,5);
    sort(s,5);
    println(s,5);

    return 0;
}

小结:
函数模板是泛型编程在C++中的应用方式之一
函数模板能够根据实参对参数类型进行推导
函数模板支持显示的指定参数类型
函数模板是C++中重要的代码复用方式

 

posted @ 2019-12-04 22:17  一代枭雄  阅读(574)  评论(0编辑  收藏  举报