假设现在要实现一个比较两个数是否相等的重载函数。

1、两个int类型的操作数比较

bool IsEqual (int left, int right)

{

     return left == right;

}

2、两个string类型的操作数比较

bool IsEqual (const string& left , const string& right)

{

     return left == right;

}


void test1 ()

{

     string s1 ("s1"), s2("s2");

     cout<<IsEqual (s1, s2)<<endl;

     cout<<IsEqual (1,1)<<endl;

}

...


如果还要比较int/char等等类型就都要分别实现一下,相似的代码重复度非常高。所以我们就要用到模板这一概念。

  • 概念

模板是泛型编程的基础。所谓泛型编程就是编写与类型无关的逻辑代码,是一种复用的方式。模板分为模板函数和模板类。

  • 模板函数

函数模板格式:

 template <class 形参名1class 形参名2, class 形参名n

  返回类型 函数名(参数列表)

 {...}


模板形参的定义既可以使用class,也可以使用typename,含义是相同的。

模板函数登场,定义一个就搞定了。

template<typename T>

bool IsEqual(const T& left, const T& right)

{

           return left == right;

}


void test1()

{

           string s1("s1" ), s2("s2");

          cout << IsEqual(s1, s2) << endl; //此处会将上面的T类型替换为string类型

          cout << IsEqual(1, 1) << endl; //此处会将上面的T类型替换为int类型

}

  • 模板参数匹配及显示实例化

template <typename T>

bool IsEqual (const T& left , const T& right )

{

     return left == right;

}


void test1 ()

{

     cout<<IsEqual (1,1)<<endl;

     //cout<<IsEqual(1,1.2)<<endl;             // 模板参数不匹配

     cout<<IsEqual<int>(1,1.2)<< endl;        // 显示实例化

     cout<<IsEqual<double>(1,1.2)<< endl;     // 显示实例化

}


  • 重载函数模板

bool IsEqual (const int& left , const int& right)

{

     return left == right;

}


template <typename T>

bool IsEqual (const T& left , const T& right )

{

     return left == right;

}


template <typename T1, typename T2>

bool IsEqual (const T1& left , const T2& right)

{

     return left == right;

}


void test1 ()

{

     cout<<IsEqual(1,1)<<endl;

     cout<<IsEqual<int>(1,1)<< endl;

     cout<<IsEqual(1,1.2)<<endl;

}


  • 模板类

普通类顺序表的定义

typedef int DataType;

//typedef char DataType;

class SeqList

{

private :     

     DataType* _data ;

     int _size ;

     int _capacity ;

};


template<typename T>

class SeqList

{

private :

     T* _data ;

     int _size ;

     int _capacity ;

};


类模板的格式

template<class 形参名1class 形参名2, ...class 形参名n>  

 class 类名

 { ... };

  • 模板类

// 动态顺序表

template<typename T>

class SeqList

{

public :

     SeqList();

    ~ SeqList();


private :

     int _size ;

     int _capacity ;

     T* _data ;

};


template <typename T>

SeqList <T>:: SeqList()

    : _size(0)

    , _capacity(10)

    , _data(new T[ _capacity])

{}


template <typename T>

SeqList <T>::~ SeqList()

{

     delete [] _data ;

}


void test1 ()

{

     SeqList<int > sl1;

     SeqList<double > sl2;

}

  • 模板总结

优点:

  1. 模板复用了代码,节省资源,更快的迭代开发,C++的标准模板库(STL)因此而产生。

  2. 增强了代码的灵活性。

缺点:

  1. 模板让代码变得凌乱复杂,不易维护,编译代码时间变长。

  2. 出现模板编译错误时,错误信息非常凌乱,不易定位错误。

模板还有一些高深晦涩的玩法,在实际运中的大多数的场景下上面的特性已经够我们玩了,所以不用去纠结模板的复杂莫测的玩法。真有兴趣深入学习的童鞋,或者有要用到一些复杂特性时,可以通过《C++ Templates 中文版》学习。