C++泛型编程--函数模板

Posted on 2018-08-05

函数模板

  • 目的:应对不同的数据类型

  • 方法:利用模板函数生成通用的函数,这些函数可以接收任意数据类型的参数,并返回任意类型的值。不必在在参数数据类型改变时再编写重载函数。

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

double sum(double a,double b)
{return a+b;}

//避免上面重复的操作,使用函数模板进行函数声明。
template <typename T>
T sum(T a,T b)
{return a+b;}

T 是一个通用的数据类型,在后面的函数中,T会是个有效的数据类型,同时定义了两个参数以及返回值的类型。但是T 并不是我我们常见的具体的数据类型。

当函数sum被调用时,实际的数据类型是什么,就会替代函数模板中出现过的T

编译器能够根据实际参数的类型推断出函数模板的类型参数

函数模板只是申明了一个函数的描述,也就是模板,不可以直接执行,必须要等到实际情况下调用的时候的实参的数据类型替代参数标识符。就可以生成真正的函数。就是模板函数。

模板函数的生成是将函数模板的类型形参实例化的过程

函数模板是一种机制,模板函数是函数模板实例化后的过程,也就是函数模板生成模板函数

使用模板函数的方法:

  • 1 说明函数模板

  • 2 实例化成相应的模板函数

  • 3 调用模板函数,并执行

  • 函数模板:

    //函数模板---使用体现:调用函数时传递的参数类型。
    template<class T>
    <返回类型>func(参数表)
    {
        //函数体
    }
    
  • 结构体模板:

    //结构体模板---使用体现:声明结构元素时 StackNode<类型> s;
    template<class T>
    struct StackNode
    {
      struct T data;
      struct StackNode<T> *next;
    };
      
    

特化模板函数

比如下面这个模板函数,去两个参数中的较大者,此模板适配于常见的int,flout,double,但是如果比较两个string, 通俗来说我们希望取长度较大的,但是在编译时,编译器会取字符的ASCII值 来比较

template <typename T>

const T& mymax(const T& a, const T& b )

{

    return a > b ? a : b ;

}

在这样的情况下,可以对函数模板进行特化,满足特定的数据类型。有了某个特定类型的模板特化之后,当使用这一类型的参数调用函数模板时,编译器将使用特化后的函数模板,而如果是其他类型的参数,仍将使用函数模板的普通版本。

// 利用模板特化,实现特定的string类型的模板函数

template <>   // 类型参数留空

// 使用实际类型string代替类型参数T

string mymax<string>( const string a, const string b )

{

    // 通过长度比较决定字符串大小

    return a.length() > b.length() ? a : b ;

}

类模板

在说明了一个 类模板 之后, 可以创建类模板实例,该实例成为 模板类 ,此时数据类型是参数。

函数(类)模板是将数据类型参数化

模板函数(类)是模板中的类型参数实例化。

这里有个重要的点,如果在类模板外定义函数,不能用一般的定义类成员函数的方式。

具体例子可以看看这个

C++ 类模板和模板类


蚊子再小也是肉~
本站总访问量 本站访客数